You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2021/05/22 20:56:49 UTC
svn commit: r1890120 [38/43] - in /poi/trunk/poi/src:
main/java/org/apache/poi/ main/java/org/apache/poi/ddf/
main/java/org/apache/poi/extractor/ main/java/org/apache/poi/hpsf/
main/java/org/apache/poi/hssf/ main/java/org/apache/poi/hssf/dev/
main/java...
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestFormulasFromSpreadsheet.java Sat May 22 20:56:44 2021
@@ -58,42 +58,42 @@ public final class TestFormulasFromSprea
private static Locale userLocale;
/**
- * This class defines constants for navigating around the test data spreadsheet used for these tests.
- */
- private interface SS {
-
- /**
- * Name of the test spreadsheet (found in the standard test data folder)
- */
- String FILENAME = "FormulaEvalTestData.xls";
- /**
- * Row (zero-based) in the test spreadsheet where the operator examples start.
- */
- int START_OPERATORS_ROW_INDEX = 22; // Row '23'
- /**
- * Row (zero-based) in the test spreadsheet where the function examples start.
- */
- int START_FUNCTIONS_ROW_INDEX = 95; // Row '96'
- /**
- * Index of the column that contains the function names
- */
- int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B'
-
- /**
- * Used to indicate when there are no more functions left
- */
- String FUNCTION_NAMES_END_SENTINEL = "<END-OF-FUNCTIONS>";
-
- /**
- * Index of the column where the test values start (for each function)
- */
- short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D'
-
- /**
- * Each function takes 4 rows in the test spreadsheet
- */
- int NUMBER_OF_ROWS_PER_FUNCTION = 4;
- }
+ * This class defines constants for navigating around the test data spreadsheet used for these tests.
+ */
+ private interface SS {
+
+ /**
+ * Name of the test spreadsheet (found in the standard test data folder)
+ */
+ String FILENAME = "FormulaEvalTestData.xls";
+ /**
+ * Row (zero-based) in the test spreadsheet where the operator examples start.
+ */
+ int START_OPERATORS_ROW_INDEX = 22; // Row '23'
+ /**
+ * Row (zero-based) in the test spreadsheet where the function examples start.
+ */
+ int START_FUNCTIONS_ROW_INDEX = 95; // Row '96'
+ /**
+ * Index of the column that contains the function names
+ */
+ int COLUMN_INDEX_FUNCTION_NAME = 1; // Column 'B'
+
+ /**
+ * Used to indicate when there are no more functions left
+ */
+ String FUNCTION_NAMES_END_SENTINEL = "<END-OF-FUNCTIONS>";
+
+ /**
+ * Index of the column where the test values start (for each function)
+ */
+ short COLUMN_INDEX_FIRST_TEST_VALUE = 3; // Column 'D'
+
+ /**
+ * Each function takes 4 rows in the test spreadsheet
+ */
+ int NUMBER_OF_ROWS_PER_FUNCTION = 4;
+ }
@AfterAll
public static void closeResource() throws Exception {
@@ -201,24 +201,24 @@ public final class TestFormulasFromSprea
}
}
}
- /**
- * @return {@code null} if cell is missing, empty or blank
- */
- private static String getTargetFunctionName(Row r) {
- if(r == null) {
- System.err.println("Warning - given null row, can't figure out function name");
- return null;
- }
- Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
- if(cell == null) {
- System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
- return null;
- }
+ /**
+ * @return {@code null} if cell is missing, empty or blank
+ */
+ private static String getTargetFunctionName(Row r) {
+ if(r == null) {
+ System.err.println("Warning - given null row, can't figure out function name");
+ return null;
+ }
+ Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
+ if(cell == null) {
+ System.err.println("Warning - Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
+ return null;
+ }
CellType ct = cell.getCellType();
assertTrue(ct == CellType.BLANK || ct == CellType.STRING,
"Bad cell type for 'function name' column: (" + cell.getCellType() + ") row (" + (r.getRowNum() +1) + ")");
return (ct == CellType.STRING) ? cell.getRichStringCellValue().getString() : null;
- }
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestHSSFCircularReferences.java Sat May 22 20:56:44 2021
@@ -23,7 +23,7 @@ import org.apache.poi.hssf.HSSFITestData
* Tests HSSFFormulaEvaluator for its handling of cell formula circular references.
*/
final class TestHSSFCircularReferences extends BaseTestCircularReferences {
- public TestHSSFCircularReferences() {
+ public TestHSSFCircularReferences() {
super(HSSFITestDataProvider.instance);
}
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMinusZeroResult.java Sat May 22 20:56:44 2021
@@ -38,113 +38,113 @@ import org.junit.jupiter.api.Test;
* </ol>
*/
final class TestMinusZeroResult {
- private static final double MINUS_ZERO = -0.0;
+ private static final double MINUS_ZERO = -0.0;
- @Test
- void testSimpleOperators() {
+ @Test
+ void testSimpleOperators() {
- // unary plus is a no-op
- checkEval(MINUS_ZERO, UnaryPlusEval.instance, MINUS_ZERO);
+ // unary plus is a no-op
+ checkEval(MINUS_ZERO, UnaryPlusEval.instance, MINUS_ZERO);
- // most simple operators convert -0.0 to +0.0
- checkEval(0.0, EvalInstances.UnaryMinus, 0.0);
- checkEval(0.0, EvalInstances.Percent, MINUS_ZERO);
- checkEval(0.0, EvalInstances.Multiply, MINUS_ZERO, 1.0);
- checkEval(0.0, EvalInstances.Divide, MINUS_ZERO, 1.0);
- checkEval(0.0, EvalInstances.Power, MINUS_ZERO, 1.0);
-
- // but SubtractEval does not convert -0.0, so '-' and '+' work like java
- checkEval(MINUS_ZERO, EvalInstances.Subtract, MINUS_ZERO, 0.0); // this is the main point of bug 47198
- checkEval(0.0, EvalInstances.Add, MINUS_ZERO, 0.0);
- }
-
- /**
- * These results are hard to see in Excel (since -0.0 is usually converted to +0.0 before it
- * gets to the comparison operator)
- */
- @Test
- void testComparisonOperators() {
- checkEval(false, EvalInstances.Equal, 0.0, MINUS_ZERO);
- checkEval(true, EvalInstances.GreaterThan, 0.0, MINUS_ZERO);
- checkEval(true, EvalInstances.LessThan, MINUS_ZERO, 0.0);
- }
-
- @Test
- void testTextRendering() {
- confirmTextRendering(MINUS_ZERO);
- // sub-normal negative numbers also display as '-0'
- confirmTextRendering(Double.longBitsToDouble(0x8000100020003000L));
- }
-
- /**
- * Uses {@link ConcatEval} to force number-to-text conversion
- */
- private static void confirmTextRendering(double d) {
- ValueEval[] args = { StringEval.EMPTY_INSTANCE, new NumberEval(d), };
- StringEval se = (StringEval) EvalInstances.Concat.evaluate(args, -1, (short)-1);
- String result = se.getStringValue();
- assertEquals("-0", result);
- }
-
- private static void checkEval(double expectedResult, Function instance, double... dArgs) {
- NumberEval result = (NumberEval) evaluate(instance, dArgs);
- assertDouble(expectedResult, result.getNumberValue());
- }
- private static void checkEval(boolean expectedResult, Function instance, double... dArgs) {
- BoolEval result = (BoolEval) evaluate(instance, dArgs);
- assertEquals(expectedResult, result.getBooleanValue());
- }
- private static ValueEval evaluate(Function instance, double... dArgs) {
- ValueEval[] evalArgs;
- evalArgs = new ValueEval[dArgs.length];
- for (int i = 0; i < evalArgs.length; i++) {
- evalArgs[i] = new NumberEval(dArgs[i]);
- }
+ // most simple operators convert -0.0 to +0.0
+ checkEval(0.0, EvalInstances.UnaryMinus, 0.0);
+ checkEval(0.0, EvalInstances.Percent, MINUS_ZERO);
+ checkEval(0.0, EvalInstances.Multiply, MINUS_ZERO, 1.0);
+ checkEval(0.0, EvalInstances.Divide, MINUS_ZERO, 1.0);
+ checkEval(0.0, EvalInstances.Power, MINUS_ZERO, 1.0);
+
+ // but SubtractEval does not convert -0.0, so '-' and '+' work like java
+ checkEval(MINUS_ZERO, EvalInstances.Subtract, MINUS_ZERO, 0.0); // this is the main point of bug 47198
+ checkEval(0.0, EvalInstances.Add, MINUS_ZERO, 0.0);
+ }
+
+ /**
+ * These results are hard to see in Excel (since -0.0 is usually converted to +0.0 before it
+ * gets to the comparison operator)
+ */
+ @Test
+ void testComparisonOperators() {
+ checkEval(false, EvalInstances.Equal, 0.0, MINUS_ZERO);
+ checkEval(true, EvalInstances.GreaterThan, 0.0, MINUS_ZERO);
+ checkEval(true, EvalInstances.LessThan, MINUS_ZERO, 0.0);
+ }
+
+ @Test
+ void testTextRendering() {
+ confirmTextRendering(MINUS_ZERO);
+ // sub-normal negative numbers also display as '-0'
+ confirmTextRendering(Double.longBitsToDouble(0x8000100020003000L));
+ }
+
+ /**
+ * Uses {@link ConcatEval} to force number-to-text conversion
+ */
+ private static void confirmTextRendering(double d) {
+ ValueEval[] args = { StringEval.EMPTY_INSTANCE, new NumberEval(d), };
+ StringEval se = (StringEval) EvalInstances.Concat.evaluate(args, -1, (short)-1);
+ String result = se.getStringValue();
+ assertEquals("-0", result);
+ }
+
+ private static void checkEval(double expectedResult, Function instance, double... dArgs) {
+ NumberEval result = (NumberEval) evaluate(instance, dArgs);
+ assertDouble(expectedResult, result.getNumberValue());
+ }
+ private static void checkEval(boolean expectedResult, Function instance, double... dArgs) {
+ BoolEval result = (BoolEval) evaluate(instance, dArgs);
+ assertEquals(expectedResult, result.getBooleanValue());
+ }
+ private static ValueEval evaluate(Function instance, double... dArgs) {
+ ValueEval[] evalArgs;
+ evalArgs = new ValueEval[dArgs.length];
+ for (int i = 0; i < evalArgs.length; i++) {
+ evalArgs[i] = new NumberEval(dArgs[i]);
+ }
return instance.evaluate(evalArgs, -1, (short)-1);
- }
+ }
- /**
- * Not really a POI test - just shows similar behaviour of '-0.0' in Java.
- */
- @Test
- void testJava() {
- assertEquals(0x8000000000000000L, Double.doubleToLongBits(MINUS_ZERO));
-
- // The simple operators consider all zeros to be the same
- //noinspection SimplifiableJUnitAssertion,ConstantConditions
- assertTrue(MINUS_ZERO == MINUS_ZERO);
- //noinspection SimplifiableJUnitAssertion,ConstantConditions
- assertTrue(MINUS_ZERO == +0.0);
- //noinspection ConstantConditions
- assertFalse(MINUS_ZERO < +0.0);
-
- // Double.compare() considers them different
- assertTrue(Double.compare(MINUS_ZERO, +0.0) < 0);
-
- // multiplying zero by any negative quantity yields minus zero
- assertDouble(MINUS_ZERO, 0.0*-1);
- assertDouble(MINUS_ZERO, 0.0*-1e300);
- assertDouble(MINUS_ZERO, 0.0*-1e-300);
-
- // minus zero can be produced as a result of underflow
- assertDouble(MINUS_ZERO, -1e-300 / 1e100);
-
- // multiplying or dividing minus zero by a positive quantity yields minus zero
- assertDouble(MINUS_ZERO, MINUS_ZERO * 1.0);
- assertDouble(MINUS_ZERO, MINUS_ZERO / 1.0);
-
- // subtracting positive zero gives minus zero
- assertDouble(MINUS_ZERO, MINUS_ZERO - 0.0);
- // BUT adding positive zero gives positive zero
- assertDouble(0.0, MINUS_ZERO + 0.0); // <<----
- }
-
- /**
- * Just so there is no ambiguity. The two double values have to be exactly equal
- */
- private static void assertDouble(double a, double b) {
- long bitsA = Double.doubleToLongBits(a);
- long bitsB = Double.doubleToLongBits(b);
- assertEquals(bitsA, bitsB);
- }
+ /**
+ * Not really a POI test - just shows similar behaviour of '-0.0' in Java.
+ */
+ @Test
+ void testJava() {
+ assertEquals(0x8000000000000000L, Double.doubleToLongBits(MINUS_ZERO));
+
+ // The simple operators consider all zeros to be the same
+ //noinspection SimplifiableJUnitAssertion,ConstantConditions
+ assertTrue(MINUS_ZERO == MINUS_ZERO);
+ //noinspection SimplifiableJUnitAssertion,ConstantConditions
+ assertTrue(MINUS_ZERO == +0.0);
+ //noinspection ConstantConditions
+ assertFalse(MINUS_ZERO < +0.0);
+
+ // Double.compare() considers them different
+ assertTrue(Double.compare(MINUS_ZERO, +0.0) < 0);
+
+ // multiplying zero by any negative quantity yields minus zero
+ assertDouble(MINUS_ZERO, 0.0*-1);
+ assertDouble(MINUS_ZERO, 0.0*-1e300);
+ assertDouble(MINUS_ZERO, 0.0*-1e-300);
+
+ // minus zero can be produced as a result of underflow
+ assertDouble(MINUS_ZERO, -1e-300 / 1e100);
+
+ // multiplying or dividing minus zero by a positive quantity yields minus zero
+ assertDouble(MINUS_ZERO, MINUS_ZERO * 1.0);
+ assertDouble(MINUS_ZERO, MINUS_ZERO / 1.0);
+
+ // subtracting positive zero gives minus zero
+ assertDouble(MINUS_ZERO, MINUS_ZERO - 0.0);
+ // BUT adding positive zero gives positive zero
+ assertDouble(0.0, MINUS_ZERO + 0.0); // <<----
+ }
+
+ /**
+ * Just so there is no ambiguity. The two double values have to be exactly equal
+ */
+ private static void assertDouble(double a, double b) {
+ long bitsA = Double.doubleToLongBits(a);
+ long bitsB = Double.doubleToLongBits(b);
+ assertEquals(bitsA, bitsB);
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMissingArgEval.java Sat May 22 20:56:44 2021
@@ -35,61 +35,61 @@ import org.junit.jupiter.api.Test;
*/
final class TestMissingArgEval {
- @Test
- void testEvaluateMissingArgs() throws IOException {
- try (HSSFWorkbook wb = new HSSFWorkbook()) {
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
- HSSFSheet sheet = wb.createSheet("Sheet1");
- HSSFCell cell = sheet.createRow(0).createCell(0);
-
- cell.setCellFormula("if(true,)");
- fe.clearAllCachedResultValues();
- // EmptyStackException -> Missing args evaluation not implemented (bug 43354)
- CellValue cv = fe.evaluate(cell);
- // MissingArg -> BlankEval -> zero (as formula result)
- assertEquals(0.0, cv.getNumberValue(), 0.0);
-
- // MissingArg -> BlankEval -> empty string (in concatenation)
- cell.setCellFormula("\"abc\"&if(true,)");
- fe.clearAllCachedResultValues();
- assertEquals("abc", fe.evaluate(cell).getStringValue());
- }
- }
-
- @Test
- void testCompareMissingArgs() throws IOException {
- try (HSSFWorkbook wb = new HSSFWorkbook()) {
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
- HSSFSheet sheet = wb.createSheet("Sheet1");
- HSSFCell cell = sheet.createRow(0).createCell(0);
-
- cell.setCellFormula("iferror(0/0,)<0");
- fe.clearAllCachedResultValues();
- CellValue cv = fe.evaluate(cell);
- assertFalse(cv.getBooleanValue());
-
- cell.setCellFormula("iferror(0/0,)<=0");
- fe.clearAllCachedResultValues();
- cv = fe.evaluate(cell);
- assertTrue(cv.getBooleanValue());
-
- cell.setCellFormula("iferror(0/0,)=0");
- fe.clearAllCachedResultValues();
- cv = fe.evaluate(cell);
- assertTrue(cv.getBooleanValue());
-
- cell.setCellFormula("iferror(0/0,)>=0");
- fe.clearAllCachedResultValues();
- cv = fe.evaluate(cell);
- assertTrue(cv.getBooleanValue());
-
- cell.setCellFormula("iferror(0/0,)>0");
- fe.clearAllCachedResultValues();
- cv = fe.evaluate(cell);
- assertFalse(cv.getBooleanValue());
+ @Test
+ void testEvaluateMissingArgs() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+ HSSFSheet sheet = wb.createSheet("Sheet1");
+ HSSFCell cell = sheet.createRow(0).createCell(0);
- // invert above for code coverage
- cell.setCellFormula("0<iferror(0/0,)");
+ cell.setCellFormula("if(true,)");
+ fe.clearAllCachedResultValues();
+ // EmptyStackException -> Missing args evaluation not implemented (bug 43354)
+ CellValue cv = fe.evaluate(cell);
+ // MissingArg -> BlankEval -> zero (as formula result)
+ assertEquals(0.0, cv.getNumberValue(), 0.0);
+
+ // MissingArg -> BlankEval -> empty string (in concatenation)
+ cell.setCellFormula("\"abc\"&if(true,)");
+ fe.clearAllCachedResultValues();
+ assertEquals("abc", fe.evaluate(cell).getStringValue());
+ }
+ }
+
+ @Test
+ void testCompareMissingArgs() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+ HSSFSheet sheet = wb.createSheet("Sheet1");
+ HSSFCell cell = sheet.createRow(0).createCell(0);
+
+ cell.setCellFormula("iferror(0/0,)<0");
+ fe.clearAllCachedResultValues();
+ CellValue cv = fe.evaluate(cell);
+ assertFalse(cv.getBooleanValue());
+
+ cell.setCellFormula("iferror(0/0,)<=0");
+ fe.clearAllCachedResultValues();
+ cv = fe.evaluate(cell);
+ assertTrue(cv.getBooleanValue());
+
+ cell.setCellFormula("iferror(0/0,)=0");
+ fe.clearAllCachedResultValues();
+ cv = fe.evaluate(cell);
+ assertTrue(cv.getBooleanValue());
+
+ cell.setCellFormula("iferror(0/0,)>=0");
+ fe.clearAllCachedResultValues();
+ cv = fe.evaluate(cell);
+ assertTrue(cv.getBooleanValue());
+
+ cell.setCellFormula("iferror(0/0,)>0");
+ fe.clearAllCachedResultValues();
+ cv = fe.evaluate(cell);
+ assertFalse(cv.getBooleanValue());
+
+ // invert above for code coverage
+ cell.setCellFormula("0<iferror(0/0,)");
fe.clearAllCachedResultValues();
cv = fe.evaluate(cell);
assertFalse(cv.getBooleanValue());
@@ -113,22 +113,22 @@ final class TestMissingArgEval {
fe.clearAllCachedResultValues();
cv = fe.evaluate(cell);
assertFalse(cv.getBooleanValue());
- }
- }
+ }
+ }
- @Test
- void testCountFuncs() throws IOException {
- try (HSSFWorkbook wb = new HSSFWorkbook()) {
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
- HSSFSheet sheet = wb.createSheet("Sheet1");
- HSSFCell cell = sheet.createRow(0).createCell(0);
-
- cell.setCellFormula("COUNT(C5,,,,)"); // 4 missing args, C5 is blank
- assertEquals(4.0, fe.evaluate(cell).getNumberValue(), 0.0);
-
- cell.setCellFormula("COUNTA(C5,,)"); // 2 missing args, C5 is blank
- fe.clearAllCachedResultValues();
- assertEquals(2.0, fe.evaluate(cell).getNumberValue(), 0.0);
- }
- }
+ @Test
+ void testCountFuncs() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+ HSSFSheet sheet = wb.createSheet("Sheet1");
+ HSSFCell cell = sheet.createRow(0).createCell(0);
+
+ cell.setCellFormula("COUNT(C5,,,,)"); // 4 missing args, C5 is blank
+ assertEquals(4.0, fe.evaluate(cell).getNumberValue(), 0.0);
+
+ cell.setCellFormula("COUNTA(C5,,)"); // 2 missing args, C5 is blank
+ fe.clearAllCachedResultValues();
+ assertEquals(2.0, fe.evaluate(cell).getNumberValue(), 0.0);
+ }
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestMultiSheetEval.java Sat May 22 20:56:44 2021
@@ -45,144 +45,144 @@ import org.junit.jupiter.params.provider
* Tests formulas for multi sheet reference (i.e. SUM(Sheet1:Sheet5!A1))
*/
final class TestMultiSheetEval {
- /**
- * This class defines constants for navigating around the test data spreadsheet used for these tests.
- */
- private static final class SS {
-
- /**
- * Name of the test spreadsheet (found in the standard test data folder)
- */
- public static final String FILENAME = "FormulaSheetRange.xls";
- /**
- * Row (zero-based) in the test spreadsheet where the function examples start.
- */
- public static final int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
- /**
- * Index of the column that contains the function names
- */
- public static final int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
- /**
- * Index of the column that contains the test names
- */
- public static final int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
- /**
- * Used to indicate when there are no more functions left
- */
- public static final String FUNCTION_NAMES_END_SENTINEL = "<END>";
-
- /**
- * Index of the column where the test expected value is present
- */
- public static final short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
- /**
- * Index of the column where the test actual value is present
- */
- public static final short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
- /**
- * Test sheet name (sheet with all test formulae)
- */
- public static final String TEST_SHEET_NAME = "test";
- }
-
- private static HSSFFormulaEvaluator evaluator;
- private static Collection<String> funcs;
-
-
- public static Stream<Arguments> data() {
- HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
- Sheet sheet = workbook.getSheet(SS.TEST_SHEET_NAME);
- evaluator = new HSSFFormulaEvaluator(workbook);
- funcs = FunctionEval.getSupportedFunctionNames();
-
- List<Arguments> data = new ArrayList<>();
- for (int rowIndex = SS.START_FUNCTIONS_ROW_INDEX;true;rowIndex++) {
- Row r = sheet.getRow(rowIndex);
-
- // only evaluate non empty row
- if (r == null) {
- continue;
- }
-
- String targetFunctionName = getTargetFunctionName(r);
- assertNotNull(targetFunctionName, "Expected function name or '" + SS.FUNCTION_NAMES_END_SENTINEL + "'");
- if (targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
- // found end of functions list
- break;
- }
- String targetTestName = getTargetTestName(r);
-
- // expected results are on the row below
- Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
- assertNotNull(expectedValueCell, "Missing expected values cell for function '" + targetFunctionName);
-
- data.add(Arguments.of( targetTestName, targetFunctionName, expectedValueCell, r ));
- }
-
- return data.stream();
- }
-
- @ParameterizedTest
- @MethodSource("data")
- void testFunction(String testName, String functionName, Cell expected, Row testRow) {
-
- Cell c = testRow.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
- if (c == null || c.getCellType() != CellType.FORMULA) {
- // missing test data
- assertTrue(testRow.getRowNum() >= SS.START_FUNCTIONS_ROW_INDEX);
- assertTrue(funcs.contains(functionName.toUpperCase(Locale.ROOT)), "unsupported function");
- return;
- }
-
- CellValue actual = evaluator.evaluate(c);
-
- assertNotNull(expected, "Bad setup data expected value is null");
- assertNotNull(actual, "actual value was null");
-
- final CellType cellType = expected.getCellType();
-
- switch (cellType) {
- case BLANK:
- assertEquals(CellType.BLANK, actual.getCellType());
- break;
- case BOOLEAN:
- assertEquals(CellType.BOOLEAN, actual.getCellType());
- assertEquals(expected.getBooleanCellValue(), actual.getBooleanValue());
- break;
- case ERROR:
- assertEquals(CellType.ERROR, actual.getCellType());
- assertEquals(ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
- break;
- case FORMULA: // will never be used, since we will call method after formula evaluation
- fail("Cannot expect formula as result of formula evaluation.");
- break;
- case NUMERIC:
- assertEquals(CellType.NUMERIC, actual.getCellType());
- TestMathX.assertDouble("", expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
- break;
- case STRING:
- assertEquals(CellType.STRING, actual.getCellType());
- assertEquals(expected.getRichStringCellValue().getString(), actual.getStringValue());
- break;
- default:
- fail("Unexpected cell type: " + cellType);
- break;
- }
- }
-
- private static String getTargetFunctionName(Row r) {
- assertNotNull(r, "given null row, can't figure out function name");
- Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
- assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
- assertEquals(CellType.STRING, cell.getCellType());
- return cell.getRichStringCellValue().getString();
- }
-
- private static String getTargetTestName(Row r) {
- assertNotNull(r, "Given null row, can't figure out test name");
- Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME);
- assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
- assertEquals(CellType.STRING, cell.getCellType());
- return cell.getRichStringCellValue().getString();
- }
+ /**
+ * This class defines constants for navigating around the test data spreadsheet used for these tests.
+ */
+ private static final class SS {
+
+ /**
+ * Name of the test spreadsheet (found in the standard test data folder)
+ */
+ public static final String FILENAME = "FormulaSheetRange.xls";
+ /**
+ * Row (zero-based) in the test spreadsheet where the function examples start.
+ */
+ public static final int START_FUNCTIONS_ROW_INDEX = 10; // Row '11'
+ /**
+ * Index of the column that contains the function names
+ */
+ public static final int COLUMN_INDEX_FUNCTION_NAME = 0; // Column 'A'
+ /**
+ * Index of the column that contains the test names
+ */
+ public static final int COLUMN_INDEX_TEST_NAME = 1; // Column 'B'
+ /**
+ * Used to indicate when there are no more functions left
+ */
+ public static final String FUNCTION_NAMES_END_SENTINEL = "<END>";
+
+ /**
+ * Index of the column where the test expected value is present
+ */
+ public static final short COLUMN_INDEX_EXPECTED_VALUE = 2; // Column 'C'
+ /**
+ * Index of the column where the test actual value is present
+ */
+ public static final short COLUMN_INDEX_ACTUAL_VALUE = 3; // Column 'D'
+ /**
+ * Test sheet name (sheet with all test formulae)
+ */
+ public static final String TEST_SHEET_NAME = "test";
+ }
+
+ private static HSSFFormulaEvaluator evaluator;
+ private static Collection<String> funcs;
+
+
+ public static Stream<Arguments> data() {
+ HSSFWorkbook workbook = HSSFTestDataSamples.openSampleWorkbook(SS.FILENAME);
+ Sheet sheet = workbook.getSheet(SS.TEST_SHEET_NAME);
+ evaluator = new HSSFFormulaEvaluator(workbook);
+ funcs = FunctionEval.getSupportedFunctionNames();
+
+ List<Arguments> data = new ArrayList<>();
+ for (int rowIndex = SS.START_FUNCTIONS_ROW_INDEX;true;rowIndex++) {
+ Row r = sheet.getRow(rowIndex);
+
+ // only evaluate non empty row
+ if (r == null) {
+ continue;
+ }
+
+ String targetFunctionName = getTargetFunctionName(r);
+ assertNotNull(targetFunctionName, "Expected function name or '" + SS.FUNCTION_NAMES_END_SENTINEL + "'");
+ if (targetFunctionName.equals(SS.FUNCTION_NAMES_END_SENTINEL)) {
+ // found end of functions list
+ break;
+ }
+ String targetTestName = getTargetTestName(r);
+
+ // expected results are on the row below
+ Cell expectedValueCell = r.getCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
+ assertNotNull(expectedValueCell, "Missing expected values cell for function '" + targetFunctionName);
+
+ data.add(Arguments.of( targetTestName, targetFunctionName, expectedValueCell, r ));
+ }
+
+ return data.stream();
+ }
+
+ @ParameterizedTest
+ @MethodSource("data")
+ void testFunction(String testName, String functionName, Cell expected, Row testRow) {
+
+ Cell c = testRow.getCell(SS.COLUMN_INDEX_ACTUAL_VALUE);
+ if (c == null || c.getCellType() != CellType.FORMULA) {
+ // missing test data
+ assertTrue(testRow.getRowNum() >= SS.START_FUNCTIONS_ROW_INDEX);
+ assertTrue(funcs.contains(functionName.toUpperCase(Locale.ROOT)), "unsupported function");
+ return;
+ }
+
+ CellValue actual = evaluator.evaluate(c);
+
+ assertNotNull(expected, "Bad setup data expected value is null");
+ assertNotNull(actual, "actual value was null");
+
+ final CellType cellType = expected.getCellType();
+
+ switch (cellType) {
+ case BLANK:
+ assertEquals(CellType.BLANK, actual.getCellType());
+ break;
+ case BOOLEAN:
+ assertEquals(CellType.BOOLEAN, actual.getCellType());
+ assertEquals(expected.getBooleanCellValue(), actual.getBooleanValue());
+ break;
+ case ERROR:
+ assertEquals(CellType.ERROR, actual.getCellType());
+ assertEquals(ErrorEval.getText(expected.getErrorCellValue()), ErrorEval.getText(actual.getErrorValue()));
+ break;
+ case FORMULA: // will never be used, since we will call method after formula evaluation
+ fail("Cannot expect formula as result of formula evaluation.");
+ break;
+ case NUMERIC:
+ assertEquals(CellType.NUMERIC, actual.getCellType());
+ TestMathX.assertDouble("", expected.getNumericCellValue(), actual.getNumberValue(), TestMathX.POS_ZERO, TestMathX.DIFF_TOLERANCE_FACTOR);
+ break;
+ case STRING:
+ assertEquals(CellType.STRING, actual.getCellType());
+ assertEquals(expected.getRichStringCellValue().getString(), actual.getStringValue());
+ break;
+ default:
+ fail("Unexpected cell type: " + cellType);
+ break;
+ }
+ }
+
+ private static String getTargetFunctionName(Row r) {
+ assertNotNull(r, "given null row, can't figure out function name");
+ Cell cell = r.getCell(SS.COLUMN_INDEX_FUNCTION_NAME);
+ assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_FUNCTION_NAME + ", can't figure out function name");
+ assertEquals(CellType.STRING, cell.getCellType());
+ return cell.getRichStringCellValue().getString();
+ }
+
+ private static String getTargetTestName(Row r) {
+ assertNotNull(r, "Given null row, can't figure out test name");
+ Cell cell = r.getCell(SS.COLUMN_INDEX_TEST_NAME);
+ assertNotNull(cell, "Row " + r.getRowNum() + " has no cell " + SS.COLUMN_INDEX_TEST_NAME + ", can't figure out test name");
+ assertEquals(CellType.STRING, cell.getCellType());
+ return cell.getRichStringCellValue().getString();
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestOperandResolver.java Sat May 22 20:56:44 2021
@@ -30,72 +30,72 @@ import org.junit.jupiter.api.Test;
* Tests for {@code OperandResolver}
*/
final class TestOperandResolver {
- @Test
- void testParseDouble_bug48472() {
- // bug 48472 - StringIndexOutOfBoundsException
- Double resolvedValue = OperandResolver.parseDouble("-");
- assertNull(resolvedValue);
- }
-
- @Test
- void testParseDouble_bug49723() {
- String value = ".1";
- Double resolvedValue = OperandResolver.parseDouble(value);
-
- assertNotNull(resolvedValue, "Identified bug 49723");
- }
-
- /**
- * Tests that a list of valid strings all return a non null value from {@link OperandResolver#parseDouble(String)}
- */
- @Test
- void testParseDoubleValidStrings() {
- String[] values = new String[]{".19", "0.19", "1.9", "1E4", "-.19", "-0.19",
- "8.5","-1E4", ".5E6","+1.5","+1E5", " +1E5 ", " 123 ", "1E4", "-123" };
-
- for (String value : values) {
- Double act = OperandResolver.parseDouble(value);
- assertNotNull(act);
- assertEquals(act, Double.parseDouble(value), 0);
- }
- }
-
- /**
- * Tests that a list of invalid strings all return null from {@link OperandResolver#parseDouble(String)}
- */
- @Test
- void testParseDoubleInvalidStrings() {
- String[] values = new String[]{"-", "ABC", "-X", "1E5a", "Infinity", "NaN", ".5F", "1,000"};
-
- for (String value : values) {
- assertNull(OperandResolver.parseDouble(value));
- }
- }
-
- @Test
- void testCoerceDateStringToNumber() throws EvaluationException {
- Map<String, Double> values = new LinkedHashMap<>();
- values.put("2019/1/18", 43483.);
- values.put("01/18/2019", 43483.);
- values.put("18 Jan 2019", 43483.);
- values.put("18-Jan-2019", 43483.);
-
- for (String str : values.keySet()) {
- assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
- }
- }
-
- @Test
- void testCoerceTimeStringToNumber() throws EvaluationException {
- Map<String, Double> values = new LinkedHashMap<>();
- values.put("00:00", 0.0);
- values.put("12:00", 0.5);
- values.put("15:43:09", 0.654965278);
- values.put("15:43", 0.654861111);
- values.put("3:43 PM", 0.654861111);
-
- for (String str : values.keySet()) {
- assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
- }
- }
+ @Test
+ void testParseDouble_bug48472() {
+ // bug 48472 - StringIndexOutOfBoundsException
+ Double resolvedValue = OperandResolver.parseDouble("-");
+ assertNull(resolvedValue);
+ }
+
+ @Test
+ void testParseDouble_bug49723() {
+ String value = ".1";
+ Double resolvedValue = OperandResolver.parseDouble(value);
+
+ assertNotNull(resolvedValue, "Identified bug 49723");
+ }
+
+ /**
+ * Tests that a list of valid strings all return a non null value from {@link OperandResolver#parseDouble(String)}
+ */
+ @Test
+ void testParseDoubleValidStrings() {
+ String[] values = new String[]{".19", "0.19", "1.9", "1E4", "-.19", "-0.19",
+ "8.5","-1E4", ".5E6","+1.5","+1E5", " +1E5 ", " 123 ", "1E4", "-123" };
+
+ for (String value : values) {
+ Double act = OperandResolver.parseDouble(value);
+ assertNotNull(act);
+ assertEquals(act, Double.parseDouble(value), 0);
+ }
+ }
+
+ /**
+ * Tests that a list of invalid strings all return null from {@link OperandResolver#parseDouble(String)}
+ */
+ @Test
+ void testParseDoubleInvalidStrings() {
+ String[] values = new String[]{"-", "ABC", "-X", "1E5a", "Infinity", "NaN", ".5F", "1,000"};
+
+ for (String value : values) {
+ assertNull(OperandResolver.parseDouble(value));
+ }
+ }
+
+ @Test
+ void testCoerceDateStringToNumber() throws EvaluationException {
+ Map<String, Double> values = new LinkedHashMap<>();
+ values.put("2019/1/18", 43483.);
+ values.put("01/18/2019", 43483.);
+ values.put("18 Jan 2019", 43483.);
+ values.put("18-Jan-2019", 43483.);
+
+ for (String str : values.keySet()) {
+ assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
+ }
+ }
+
+ @Test
+ void testCoerceTimeStringToNumber() throws EvaluationException {
+ Map<String, Double> values = new LinkedHashMap<>();
+ values.put("00:00", 0.0);
+ values.put("12:00", 0.5);
+ values.put("15:43:09", 0.654965278);
+ values.put("15:43", 0.654861111);
+ values.put("3:43 PM", 0.654861111);
+
+ for (String str : values.keySet()) {
+ assertEquals(OperandResolver.coerceValueToDouble(new StringEval(str)), values.get(str), 0.00001);
+ }
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestPercentEval.java Sat May 22 20:56:44 2021
@@ -37,46 +37,46 @@ import org.junit.jupiter.api.Test;
*/
final class TestPercentEval {
- private static void confirm(ValueEval arg, double expectedResult) {
- ValueEval[] args = {
- arg,
- };
-
- double result = NumericFunctionInvoker.invoke(PercentEval.instance, args, 0, 0);
-
- assertEquals(expectedResult, result, 0);
- }
-
- @Test
- void testBasic() {
- confirm(new NumberEval(5), 0.05);
- confirm(new NumberEval(3000), 30.0);
- confirm(new NumberEval(-150), -1.5);
- confirm(new StringEval("0.2"), 0.002);
- confirm(BoolEval.TRUE, 0.01);
- }
-
- @Test
- void test1x1Area() {
- AreaEval ae = EvalFactory.createAreaEval("B2:B2", new ValueEval[] { new NumberEval(50), });
- confirm(ae, 0.5);
- }
-
- @Test
- void testInSpreadSheet() throws IOException {
- try (HSSFWorkbook wb = new HSSFWorkbook()) {
- HSSFSheet sheet = wb.createSheet("Sheet1");
- HSSFRow row = sheet.createRow(0);
- HSSFCell cell = row.createCell(0);
- cell.setCellFormula("B1%");
- row.createCell(1).setCellValue(50.0);
-
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
-
- // bug 44608 - NullPointerException
- CellValue cv = fe.evaluate(cell);
- assertEquals(CellType.NUMERIC, cv.getCellType());
- assertEquals(0.5, cv.getNumberValue(), 0.0);
- }
- }
+ private static void confirm(ValueEval arg, double expectedResult) {
+ ValueEval[] args = {
+ arg,
+ };
+
+ double result = NumericFunctionInvoker.invoke(PercentEval.instance, args, 0, 0);
+
+ assertEquals(expectedResult, result, 0);
+ }
+
+ @Test
+ void testBasic() {
+ confirm(new NumberEval(5), 0.05);
+ confirm(new NumberEval(3000), 30.0);
+ confirm(new NumberEval(-150), -1.5);
+ confirm(new StringEval("0.2"), 0.002);
+ confirm(BoolEval.TRUE, 0.01);
+ }
+
+ @Test
+ void test1x1Area() {
+ AreaEval ae = EvalFactory.createAreaEval("B2:B2", new ValueEval[] { new NumberEval(50), });
+ confirm(ae, 0.5);
+ }
+
+ @Test
+ void testInSpreadSheet() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFSheet sheet = wb.createSheet("Sheet1");
+ HSSFRow row = sheet.createRow(0);
+ HSSFCell cell = row.createCell(0);
+ cell.setCellFormula("B1%");
+ row.createCell(1).setCellValue(50.0);
+
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+
+ // bug 44608 - NullPointerException
+ CellValue cv = fe.evaluate(cell);
+ assertEquals(CellType.NUMERIC, cv.getCellType());
+ assertEquals(0.5, cv.getNumberValue(), 0.0);
+ }
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestRangeEval.java Sat May 22 20:56:44 2021
@@ -40,130 +40,130 @@ import org.junit.jupiter.api.Test;
* Test for unary plus operator evaluator.
*/
final class TestRangeEval {
- @Test
- void testPermutations() {
+ @Test
+ void testPermutations() {
- confirm("B3", "D7", "B3:D7");
- confirm("B1", "B1", "B1:B1");
+ confirm("B3", "D7", "B3:D7");
+ confirm("B1", "B1", "B1:B1");
- confirm("B7", "D3", "B3:D7");
- confirm("D3", "B7", "B3:D7");
- confirm("D7", "B3", "B3:D7");
- }
-
- private static void confirm(String refA, String refB, String expectedAreaRef) {
-
- ValueEval[] args = {
- createRefEval(refA),
- createRefEval(refB),
- };
+ confirm("B7", "D3", "B3:D7");
+ confirm("D3", "B7", "B3:D7");
+ confirm("D7", "B3", "B3:D7");
+ }
+
+ private static void confirm(String refA, String refB, String expectedAreaRef) {
+
+ ValueEval[] args = {
+ createRefEval(refA),
+ createRefEval(refB),
+ };
List<SpreadsheetVersion> versions = Arrays.asList(SpreadsheetVersion.EXCEL97, SpreadsheetVersion.EXCEL2007);
for(SpreadsheetVersion version : versions) {
AreaReference ar = new AreaReference(expectedAreaRef, version);
- ValueEval result = EvalInstances.Range.evaluate(args, 0, (short)0);
- assertTrue(result instanceof AreaEval);
- AreaEval ae = (AreaEval) result;
- assertEquals(ar.getFirstCell().getRow(), ae.getFirstRow());
- assertEquals(ar.getLastCell().getRow(), ae.getLastRow());
- assertEquals(ar.getFirstCell().getCol(), ae.getFirstColumn());
- assertEquals(ar.getLastCell().getCol(), ae.getLastColumn());
- }
- }
-
- private static ValueEval createRefEval(String refStr) {
- CellReference cr = new CellReference(refStr);
- return new MockRefEval(cr.getRow(), cr.getCol());
-
- }
-
- private static final class MockRefEval extends RefEvalBase {
- public MockRefEval(int rowIndex, int columnIndex) {
- super(-1, -1, rowIndex, columnIndex);
- }
- @Override
+ ValueEval result = EvalInstances.Range.evaluate(args, 0, (short)0);
+ assertTrue(result instanceof AreaEval);
+ AreaEval ae = (AreaEval) result;
+ assertEquals(ar.getFirstCell().getRow(), ae.getFirstRow());
+ assertEquals(ar.getLastCell().getRow(), ae.getLastRow());
+ assertEquals(ar.getFirstCell().getCol(), ae.getFirstColumn());
+ assertEquals(ar.getLastCell().getCol(), ae.getLastColumn());
+ }
+ }
+
+ private static ValueEval createRefEval(String refStr) {
+ CellReference cr = new CellReference(refStr);
+ return new MockRefEval(cr.getRow(), cr.getCol());
+
+ }
+
+ private static final class MockRefEval extends RefEvalBase {
+ public MockRefEval(int rowIndex, int columnIndex) {
+ super(-1, -1, rowIndex, columnIndex);
+ }
+ @Override
public ValueEval getInnerValueEval(int sheetIndex) {
- throw new RuntimeException("not expected to be called during this test");
- }
- @Override
+ throw new RuntimeException("not expected to be called during this test");
+ }
+ @Override
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx,
- int relLastColIx) {
- AreaI area = new OffsetArea(getRow(), getColumn(),
- relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
- return new MockAreaEval(area);
- }
- }
-
- private static final class MockAreaEval extends AreaEvalBase {
-
- public MockAreaEval(AreaI ptg) {
- super(ptg);
- }
- private MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
- super(firstRow, firstColumn, lastRow, lastColumn);
- }
- @Override
+ int relLastColIx) {
+ AreaI area = new OffsetArea(getRow(), getColumn(),
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+ return new MockAreaEval(area);
+ }
+ }
+
+ private static final class MockAreaEval extends AreaEvalBase {
+
+ public MockAreaEval(AreaI ptg) {
+ super(ptg);
+ }
+ private MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
+ super(firstRow, firstColumn, lastRow, lastColumn);
+ }
+ @Override
public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
- throw new RuntimeException("not expected to be called during this test");
- }
+ throw new RuntimeException("not expected to be called during this test");
+ }
@Override
public ValueEval getRelativeValue(int sheetIndex, int relativeRowIndex, int relativeColumnIndex) {
throw new RuntimeException("not expected to be called during this test");
}
- @Override
+ @Override
public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx,
- int relLastColIx) {
- AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
- relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
-
- return new MockAreaEval(area);
- }
- @Override
+ int relLastColIx) {
+ AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+
+ return new MockAreaEval(area);
+ }
+ @Override
public TwoDEval getRow(int rowIndex) {
- if (rowIndex >= getHeight()) {
- throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
- + ". Allowable range is (0.." + getHeight() + ").");
- }
- return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn());
- }
- @Override
+ if (rowIndex >= getHeight()) {
+ throw new IllegalArgumentException("Invalid rowIndex " + rowIndex
+ + ". Allowable range is (0.." + getHeight() + ").");
+ }
+ return new MockAreaEval(rowIndex, getFirstColumn(), rowIndex, getLastColumn());
+ }
+ @Override
public TwoDEval getColumn(int columnIndex) {
- if (columnIndex >= getWidth()) {
- throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
- + ". Allowable range is (0.." + getWidth() + ").");
- }
- return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex);
- }
- }
-
- @Test
- void testRangeUsingOffsetFunc_bug46948() {
- HSSFWorkbook wb = new HSSFWorkbook();
- HSSFRow row = wb.createSheet("Sheet1").createRow(0);
- HSSFCell cellA1 = row.createCell(0);
- HSSFCell cellB1 = row.createCell(1);
- row.createCell(2).setCellValue(5.0); // C1
- row.createCell(3).setCellValue(7.0); // D1
- row.createCell(4).setCellValue(9.0); // E1
-
-
- cellA1.setCellFormula("SUM(C1:OFFSET(C1,0,B1))");
-
- cellB1.setCellValue(1.0); // range will be C1:D1
-
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
- // bug 46948 - Unexpected ref arg class (org.apache.poi.ss.formula.LazyAreaEval)
- CellValue cv = fe.evaluate(cellA1);
-
- assertEquals(12.0, cv.getNumberValue(), 0.0);
-
- cellB1.setCellValue(2.0); // range will be C1:E1
- fe.notifyUpdateCell(cellB1);
- cv = fe.evaluate(cellA1);
- assertEquals(21.0, cv.getNumberValue(), 0.0);
-
- cellB1.setCellValue(0.0); // range will be C1:C1
- fe.notifyUpdateCell(cellB1);
- cv = fe.evaluate(cellA1);
- assertEquals(5.0, cv.getNumberValue(), 0.0);
- }
+ if (columnIndex >= getWidth()) {
+ throw new IllegalArgumentException("Invalid columnIndex " + columnIndex
+ + ". Allowable range is (0.." + getWidth() + ").");
+ }
+ return new MockAreaEval(getFirstRow(), columnIndex, getLastRow(), columnIndex);
+ }
+ }
+
+ @Test
+ void testRangeUsingOffsetFunc_bug46948() {
+ HSSFWorkbook wb = new HSSFWorkbook();
+ HSSFRow row = wb.createSheet("Sheet1").createRow(0);
+ HSSFCell cellA1 = row.createCell(0);
+ HSSFCell cellB1 = row.createCell(1);
+ row.createCell(2).setCellValue(5.0); // C1
+ row.createCell(3).setCellValue(7.0); // D1
+ row.createCell(4).setCellValue(9.0); // E1
+
+
+ cellA1.setCellFormula("SUM(C1:OFFSET(C1,0,B1))");
+
+ cellB1.setCellValue(1.0); // range will be C1:D1
+
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
+ // bug 46948 - Unexpected ref arg class (org.apache.poi.ss.formula.LazyAreaEval)
+ CellValue cv = fe.evaluate(cellA1);
+
+ assertEquals(12.0, cv.getNumberValue(), 0.0);
+
+ cellB1.setCellValue(2.0); // range will be C1:E1
+ fe.notifyUpdateCell(cellB1);
+ cv = fe.evaluate(cellA1);
+ assertEquals(21.0, cv.getNumberValue(), 0.0);
+
+ cellB1.setCellValue(0.0); // range will be C1:C1
+ fe.notifyUpdateCell(cellB1);
+ cv = fe.evaluate(cellA1);
+ assertEquals(5.0, cv.getNumberValue(), 0.0);
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/TestUnaryPlusEval.java Sat May 22 20:56:44 2021
@@ -29,30 +29,30 @@ import org.junit.jupiter.api.Test;
*/
final class TestUnaryPlusEval {
- /**
- * Test for bug observable at svn revision 618865 (5-Feb-2008)<br>
- * The code for handling column operands had been copy-pasted from the row handling code.
- */
- @Test
- void testColumnOperand() {
+ /**
+ * Test for bug observable at svn revision 618865 (5-Feb-2008)<br>
+ * The code for handling column operands had been copy-pasted from the row handling code.
+ */
+ @Test
+ void testColumnOperand() {
- short firstRow = (short)8;
- short lastRow = (short)12;
- short colNum = (short)5;
- AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false);
- ValueEval[] values = {
- new NumberEval(27),
- new NumberEval(29),
- new NumberEval(35), // value in row 10
- new NumberEval(37),
- new NumberEval(38),
- };
- ValueEval[] args = {
- EvalFactory.createAreaEval(areaPtg, values),
- };
+ short firstRow = (short)8;
+ short lastRow = (short)12;
+ short colNum = (short)5;
+ AreaPtg areaPtg = new AreaPtg(firstRow, lastRow, colNum, colNum, false, false, false, false);
+ ValueEval[] values = {
+ new NumberEval(27),
+ new NumberEval(29),
+ new NumberEval(35), // value in row 10
+ new NumberEval(37),
+ new NumberEval(38),
+ };
+ ValueEval[] args = {
+ EvalFactory.createAreaEval(areaPtg, values),
+ };
- double result = NumericFunctionInvoker.invoke(EvalInstances.UnaryPlus, args, 10, (short)20);
+ double result = NumericFunctionInvoker.invoke(EvalInstances.UnaryPlus, args, 10, (short)20);
- assertEquals(35, result, 0);
- }
+ assertEquals(35, result, 0);
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/eval/forked/BaseTestForkedEvaluator.java Sat May 22 20:56:44 2021
@@ -37,81 +37,81 @@ public class BaseTestForkedEvaluator {
return new HSSFWorkbook();
}
- /**
- * set up a calculation workbook with input cells nicely segregated on a
- * sheet called "Inputs"
- */
- protected Workbook createWorkbook() {
- Workbook wb = newWorkbook();
- Sheet sheet1 = wb.createSheet("Inputs");
- Sheet sheet2 = wb.createSheet("Calculations");
- Row row;
- row = sheet2.createRow(0);
- row.createCell(0).setCellFormula("B1*Inputs!A1-Inputs!B1");
- row.createCell(1).setCellValue(5.0); // Calculations!B1
-
- // some default input values
- row = sheet1.createRow(0);
- row.createCell(0).setCellValue(2.0); // Inputs!A1
- row.createCell(1).setCellValue(3.0); // Inputs!B1
- return wb;
- }
-
- /**
- * Shows a basic use-case for {@link ForkedEvaluator}
- */
- @Test
- void testBasic() throws IOException {
- try (Workbook wb = createWorkbook()) {
-
- // The stability classifier is useful to reduce memory consumption of caching logic
- IStabilityClassifier stabilityClassifier = (sheetIndex, rowIndex, columnIndex) -> sheetIndex == 1;
-
- ForkedEvaluator fe1 = ForkedEvaluator.create(wb, stabilityClassifier, null);
- ForkedEvaluator fe2 = ForkedEvaluator.create(wb, stabilityClassifier, null);
-
- // fe1 and fe2 can be used concurrently on separate threads
-
- fe1.updateCell("Inputs", 0, 0, new NumberEval(4.0));
- fe1.updateCell("Inputs", 0, 1, new NumberEval(1.1));
-
- fe2.updateCell("Inputs", 0, 0, new NumberEval(1.2));
- fe2.updateCell("Inputs", 0, 1, new NumberEval(2.0));
-
- NumberEval eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
- assertNotNull(eval1);
- assertEquals(18.9, eval1.getNumberValue(), 0.0);
- NumberEval eval2 = (NumberEval) fe2.evaluate("Calculations", 0, 0);
- assertNotNull(eval2);
- assertEquals(4.0, eval2.getNumberValue(), 0.0);
- fe1.updateCell("Inputs", 0, 0, new NumberEval(3.0));
- eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
- assertNotNull(eval1);
- assertEquals(13.9, eval1.getNumberValue(), 0.0);
- }
- }
-
- /**
- * As of Sep 2009, the Forked evaluator can update values from existing cells (this is because
- * the underlying 'master' cell is used as a key into the calculation cache. Prior to the fix
- * for this bug, an attempt to update a missing cell would result in NPE. This junit tests for
- * a more meaningful error message.<br>
- *
- * An alternate solution might involve allowing empty cells to be created as necessary. That
- * was considered less desirable because so far, the underlying 'master' workbook is strictly
- * <i>read-only</i> with respect to the ForkedEvaluator.
- */
- @Test
- void testMissingInputCellH() throws IOException {
-
- try (Workbook wb = createWorkbook()) {
- ForkedEvaluator fe = ForkedEvaluator.create(wb, null, null);
- // attempt update input at cell A2 (which is missing)
- UnsupportedOperationException ex = assertThrows(
- UnsupportedOperationException.class,
- () -> fe.updateCell("Inputs", 1, 0, new NumberEval(4.0))
- );
- assertEquals("Underlying cell 'A2' is missing in master sheet.", ex.getMessage());
- }
- }
+ /**
+ * set up a calculation workbook with input cells nicely segregated on a
+ * sheet called "Inputs"
+ */
+ protected Workbook createWorkbook() {
+ Workbook wb = newWorkbook();
+ Sheet sheet1 = wb.createSheet("Inputs");
+ Sheet sheet2 = wb.createSheet("Calculations");
+ Row row;
+ row = sheet2.createRow(0);
+ row.createCell(0).setCellFormula("B1*Inputs!A1-Inputs!B1");
+ row.createCell(1).setCellValue(5.0); // Calculations!B1
+
+ // some default input values
+ row = sheet1.createRow(0);
+ row.createCell(0).setCellValue(2.0); // Inputs!A1
+ row.createCell(1).setCellValue(3.0); // Inputs!B1
+ return wb;
+ }
+
+ /**
+ * Shows a basic use-case for {@link ForkedEvaluator}
+ */
+ @Test
+ void testBasic() throws IOException {
+ try (Workbook wb = createWorkbook()) {
+
+ // The stability classifier is useful to reduce memory consumption of caching logic
+ IStabilityClassifier stabilityClassifier = (sheetIndex, rowIndex, columnIndex) -> sheetIndex == 1;
+
+ ForkedEvaluator fe1 = ForkedEvaluator.create(wb, stabilityClassifier, null);
+ ForkedEvaluator fe2 = ForkedEvaluator.create(wb, stabilityClassifier, null);
+
+ // fe1 and fe2 can be used concurrently on separate threads
+
+ fe1.updateCell("Inputs", 0, 0, new NumberEval(4.0));
+ fe1.updateCell("Inputs", 0, 1, new NumberEval(1.1));
+
+ fe2.updateCell("Inputs", 0, 0, new NumberEval(1.2));
+ fe2.updateCell("Inputs", 0, 1, new NumberEval(2.0));
+
+ NumberEval eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
+ assertNotNull(eval1);
+ assertEquals(18.9, eval1.getNumberValue(), 0.0);
+ NumberEval eval2 = (NumberEval) fe2.evaluate("Calculations", 0, 0);
+ assertNotNull(eval2);
+ assertEquals(4.0, eval2.getNumberValue(), 0.0);
+ fe1.updateCell("Inputs", 0, 0, new NumberEval(3.0));
+ eval1 = (NumberEval) fe1.evaluate("Calculations", 0, 0);
+ assertNotNull(eval1);
+ assertEquals(13.9, eval1.getNumberValue(), 0.0);
+ }
+ }
+
+ /**
+ * As of Sep 2009, the Forked evaluator can update values from existing cells (this is because
+ * the underlying 'master' cell is used as a key into the calculation cache. Prior to the fix
+ * for this bug, an attempt to update a missing cell would result in NPE. This junit tests for
+ * a more meaningful error message.<br>
+ *
+ * An alternate solution might involve allowing empty cells to be created as necessary. That
+ * was considered less desirable because so far, the underlying 'master' workbook is strictly
+ * <i>read-only</i> with respect to the ForkedEvaluator.
+ */
+ @Test
+ void testMissingInputCellH() throws IOException {
+
+ try (Workbook wb = createWorkbook()) {
+ ForkedEvaluator fe = ForkedEvaluator.create(wb, null, null);
+ // attempt update input at cell A2 (which is missing)
+ UnsupportedOperationException ex = assertThrows(
+ UnsupportedOperationException.class,
+ () -> fe.updateCell("Inputs", 1, 0, new NumberEval(4.0))
+ );
+ assertEquals("Underlying cell 'A2' is missing in master sheet.", ex.getMessage());
+ }
+ }
}
Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java?rev=1890120&r1=1890119&r2=1890120&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/formula/function/ExcelCetabFunctionExtractor.java Sat May 22 20:56:44 2021
@@ -43,336 +43,336 @@ import java.util.regex.Pattern;
*/
public final class ExcelCetabFunctionExtractor {
- private static final String SOURCE_DOC_FILE_NAME = "functionMetadataCetab-PDF.txt";
+ private static final String SOURCE_DOC_FILE_NAME = "functionMetadataCetab-PDF.txt";
- /**
- * For simplicity, the output file is strictly simple ASCII.
- * This method detects any unexpected characters.
- */
- /* package */ static boolean isSimpleAscii(char c) {
-
- if (c>=0x21 && c<=0x7E) {
- // everything from '!' to '~' (includes letters, digits, punctuation
- return true;
- }
- // some specific whitespace chars below 0x21:
- switch(c) {
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- return true;
- }
- return false;
- }
-
-
- private static final class FunctionData {
- // special characters from the ooo document
- private static final int CHAR_ELLIPSIS_8230 = 8230;
- private static final int CHAR_NDASH_8211 = 8211;
-
- private final int _index;
- private final boolean _hasFootnote;
- private final String _name;
- private final int _minParams;
- private final int _maxParams;
- private final String _returnClass;
- private final String _paramClasses;
- private final boolean _isVolatile;
-
- public FunctionData(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
- String returnClass, String paramClasses, boolean isVolatile) {
- _index = funcIx;
- _hasFootnote = hasFootnote;
- _name = funcName;
- _minParams = minParams;
- _maxParams = maxParams;
- _returnClass = convertSpecialChars(returnClass);
- _paramClasses = convertSpecialChars(paramClasses);
- _isVolatile = isVolatile;
- }
- private static String convertSpecialChars(String ss) {
- StringBuilder sb = new StringBuilder(ss.length() + 4);
- for(int i=0; i<ss.length(); i++) {
- char c = ss.charAt(i);
- if (isSimpleAscii(c)) {
- sb.append(c);
- continue;
- }
- switch (c) {
- case CHAR_NDASH_8211:
- sb.append('-');
- continue;
- case CHAR_ELLIPSIS_8230:
- sb.append("...");
- continue;
- }
- throw new RuntimeException("bad char (" + ((int)c) + ") in string '" + ss + "'");
- }
- return sb.toString();
- }
- public int getIndex() {
- return _index;
- }
- public String getName() {
- return _name;
- }
- public boolean hasFootnote() {
- return _hasFootnote;
- }
- public String formatAsDataLine() {
- return _index + "\t" + _name + "\t" + _minParams + "\t"
- + _maxParams + "\t" + _returnClass + "\t" + _paramClasses
- + "\t" + checkMark(_isVolatile) + "\t" + checkMark(_hasFootnote);
- }
- private static String checkMark(boolean b) {
- return b ? "x" : "";
- }
- }
-
- private static final class FunctionDataCollector {
-
- private final Map<Integer, FunctionData> _allFunctionsByIndex;
- private final Map<String, FunctionData> _allFunctionsByName;
- private final Set<Integer> _groupFunctionIndexes;
- private final Set<String> _groupFunctionNames;
- private final PrintStream _ps;
-
- public FunctionDataCollector(PrintStream ps) {
- _ps = ps;
- _allFunctionsByIndex = new HashMap<>();
- _allFunctionsByName = new HashMap<>();
- _groupFunctionIndexes = new HashSet<>();
- _groupFunctionNames = new HashSet<>();
- }
-
- public void addFunction(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
- String returnClass, String paramClasses, String volatileFlagStr) {
- boolean isVolatile = volatileFlagStr.length() > 0;
-
- Integer funcIxKey = Integer.valueOf(funcIx);
- if(!_groupFunctionIndexes.add(funcIxKey)) {
- throw new RuntimeException("Duplicate function index (" + funcIx + ")");
- }
- if(!_groupFunctionNames.add(funcName)) {
- throw new RuntimeException("Duplicate function name '" + funcName + "'");
- }
-
- checkRedefinedFunction(hasFootnote, funcName, funcIxKey);
- FunctionData fd = new FunctionData(funcIx, hasFootnote, funcName,
- minParams, maxParams, returnClass, paramClasses, isVolatile);
-
- _allFunctionsByIndex.put(funcIxKey, fd);
- _allFunctionsByName.put(funcName, fd);
- }
-
- /**
- * Some extra validation here.
- * Any function which changes definition will have a footnote in the source document
- */
- private void checkRedefinedFunction(boolean hasNote, String funcName, Integer funcIxKey) {
- FunctionData fdPrev;
- // check by index
- fdPrev = _allFunctionsByIndex.get(funcIxKey);
- if(fdPrev != null) {
- if(!fdPrev.hasFootnote() || !hasNote) {
- throw new RuntimeException("changing function ["
- + funcIxKey + "] definition without foot-note");
- }
- _allFunctionsByName.remove(fdPrev.getName());
- }
- // check by name
- fdPrev = _allFunctionsByName.get(funcName);
- if(fdPrev != null) {
- if(!fdPrev.hasFootnote() || !hasNote) {
- throw new RuntimeException("changing function '"
- + funcName + "' definition without foot-note");
- }
- _allFunctionsByIndex.remove(Integer.valueOf(fdPrev.getIndex()));
- }
- }
-
- public void endTableGroup(String headingText) {
- Integer[] keys = new Integer[_groupFunctionIndexes.size()];
- _groupFunctionIndexes.toArray(keys);
- _groupFunctionIndexes.clear();
- _groupFunctionNames.clear();
- Arrays.sort(keys);
-
- _ps.println("# " + headingText);
- for (Integer key : keys) {
- FunctionData fd = _allFunctionsByIndex.get(key);
- _ps.println(fd.formatAsDataLine());
- }
- }
- }
-
- private static final Pattern ID_MATCH = Pattern.compile("0x([\\dA-F]+)");
- private static final Pattern NAME_MATCH = Pattern.compile("([0-9A-Z.]+)");
- private static final Pattern ID_NAME_MATCH = Pattern.compile("0x([\\dA-F]+)\\s+([0-9A-Z.]+)");
-
- private static final Set<String> IGNORED_LINES = new HashSet<>();
- static {
- IGNORED_LINES.add("[MS-XLS] â v20141018");
- IGNORED_LINES.add("Excel Binary File Format (.xls) Structure");
- IGNORED_LINES.add("Copyright © 2014 Microsoft Corporation.");
- IGNORED_LINES.add("Release: October 30, 2014Value Meaning");
- IGNORED_LINES.add("Release: October 30, 2014Value");
- IGNORED_LINES.add("Meaning");
- }
-
- private static void extractFunctionData(FunctionDataCollector fdc, InputStream is) throws IOException {
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
-
- String id = null;
- String name = null;
- while (true) {
- String line = reader.readLine();
- if(line == null) {
- break;
- }
-
- if(IGNORED_LINES.contains(line) || line.matches("\\d+ / \\d+")) {
- continue;
- }
-
- Matcher idMatcher = ID_MATCH.matcher(line);
- boolean foundID = idMatcher.matches();
- Matcher nameMatcher = NAME_MATCH.matcher(line);
- boolean foundName = nameMatcher.matches();
- Matcher idAndNameMatcher = ID_NAME_MATCH.matcher(line);
- boolean foundIDandName = idAndNameMatcher.matches();
- if(foundID && foundName ||
- foundName && foundIDandName ||
- foundID && foundIDandName) {
- throw new IllegalStateException("Should not find id and name: " +
- foundID + "/" + foundName + "/" + foundIDandName +
- ", line: " + line);
- }
-
- if(foundID && id != null) {
- throw new IllegalStateException("Found ID, but already had one: " + id + ", line: " + line);
- }
- if(foundName && name != null) {
- throw new IllegalStateException("Found name, but already had one: " + name + ", line: " + line);
- }
- if(foundIDandName && (name != null || id != null)) {
- throw new IllegalStateException("Found name and id, but already had one: id: " + id + ", name: " + name + ", line: " + line);
- }
-
- if(foundID) {
- id = idMatcher.group(1);
- } else if (foundName) {
- name = nameMatcher.group(1);
- } else if (foundIDandName) {
- id = idAndNameMatcher.group(1);
- name = idAndNameMatcher.group(2);
- // manual override for one function name which contains lowercase characters
- } else if(line.equals("VBAActivate")) {
- name = line;
- } else if (id == null || name == null) {
- throw new IllegalStateException("Found params, but had empty id or name, id: " + id +
- ", name: " + name + ", line: " + line);
- } else {
- System.out.println("Found function " + id + " " + name + " " + line);
- fdc.addFunction(Integer.parseInt(id, 16), false, name, 0, 0,
- "", "", "");
-
- id = null;
- name = null;
- }
- }
- }
-
- fdc.endTableGroup("");
- }
- /**
- * To be sure that no tricky unicode chars make it through to the output file.
- */
- private static final class SimpleAsciiOutputStream extends OutputStream {
-
- private final OutputStream _os;
-
- public SimpleAsciiOutputStream(OutputStream os) {
- _os = os;
- }
-
- @Override
+ /**
+ * For simplicity, the output file is strictly simple ASCII.
+ * This method detects any unexpected characters.
+ */
+ /* package */ static boolean isSimpleAscii(char c) {
+
+ if (c>=0x21 && c<=0x7E) {
+ // everything from '!' to '~' (includes letters, digits, punctuation
+ return true;
+ }
+ // some specific whitespace chars below 0x21:
+ switch(c) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ return true;
+ }
+ return false;
+ }
+
+
+ private static final class FunctionData {
+ // special characters from the ooo document
+ private static final int CHAR_ELLIPSIS_8230 = 8230;
+ private static final int CHAR_NDASH_8211 = 8211;
+
+ private final int _index;
+ private final boolean _hasFootnote;
+ private final String _name;
+ private final int _minParams;
+ private final int _maxParams;
+ private final String _returnClass;
+ private final String _paramClasses;
+ private final boolean _isVolatile;
+
+ public FunctionData(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
+ String returnClass, String paramClasses, boolean isVolatile) {
+ _index = funcIx;
+ _hasFootnote = hasFootnote;
+ _name = funcName;
+ _minParams = minParams;
+ _maxParams = maxParams;
+ _returnClass = convertSpecialChars(returnClass);
+ _paramClasses = convertSpecialChars(paramClasses);
+ _isVolatile = isVolatile;
+ }
+ private static String convertSpecialChars(String ss) {
+ StringBuilder sb = new StringBuilder(ss.length() + 4);
+ for(int i=0; i<ss.length(); i++) {
+ char c = ss.charAt(i);
+ if (isSimpleAscii(c)) {
+ sb.append(c);
+ continue;
+ }
+ switch (c) {
+ case CHAR_NDASH_8211:
+ sb.append('-');
+ continue;
+ case CHAR_ELLIPSIS_8230:
+ sb.append("...");
+ continue;
+ }
+ throw new RuntimeException("bad char (" + ((int)c) + ") in string '" + ss + "'");
+ }
+ return sb.toString();
+ }
+ public int getIndex() {
+ return _index;
+ }
+ public String getName() {
+ return _name;
+ }
+ public boolean hasFootnote() {
+ return _hasFootnote;
+ }
+ public String formatAsDataLine() {
+ return _index + "\t" + _name + "\t" + _minParams + "\t"
+ + _maxParams + "\t" + _returnClass + "\t" + _paramClasses
+ + "\t" + checkMark(_isVolatile) + "\t" + checkMark(_hasFootnote);
+ }
+ private static String checkMark(boolean b) {
+ return b ? "x" : "";
+ }
+ }
+
+ private static final class FunctionDataCollector {
+
+ private final Map<Integer, FunctionData> _allFunctionsByIndex;
+ private final Map<String, FunctionData> _allFunctionsByName;
+ private final Set<Integer> _groupFunctionIndexes;
+ private final Set<String> _groupFunctionNames;
+ private final PrintStream _ps;
+
+ public FunctionDataCollector(PrintStream ps) {
+ _ps = ps;
+ _allFunctionsByIndex = new HashMap<>();
+ _allFunctionsByName = new HashMap<>();
+ _groupFunctionIndexes = new HashSet<>();
+ _groupFunctionNames = new HashSet<>();
+ }
+
+ public void addFunction(int funcIx, boolean hasFootnote, String funcName, int minParams, int maxParams,
+ String returnClass, String paramClasses, String volatileFlagStr) {
+ boolean isVolatile = volatileFlagStr.length() > 0;
+
+ Integer funcIxKey = Integer.valueOf(funcIx);
+ if(!_groupFunctionIndexes.add(funcIxKey)) {
+ throw new RuntimeException("Duplicate function index (" + funcIx + ")");
+ }
+ if(!_groupFunctionNames.add(funcName)) {
+ throw new RuntimeException("Duplicate function name '" + funcName + "'");
+ }
+
+ checkRedefinedFunction(hasFootnote, funcName, funcIxKey);
+ FunctionData fd = new FunctionData(funcIx, hasFootnote, funcName,
+ minParams, maxParams, returnClass, paramClasses, isVolatile);
+
+ _allFunctionsByIndex.put(funcIxKey, fd);
+ _allFunctionsByName.put(funcName, fd);
+ }
+
+ /**
+ * Some extra validation here.
+ * Any function which changes definition will have a footnote in the source document
+ */
+ private void checkRedefinedFunction(boolean hasNote, String funcName, Integer funcIxKey) {
+ FunctionData fdPrev;
+ // check by index
+ fdPrev = _allFunctionsByIndex.get(funcIxKey);
+ if(fdPrev != null) {
+ if(!fdPrev.hasFootnote() || !hasNote) {
+ throw new RuntimeException("changing function ["
+ + funcIxKey + "] definition without foot-note");
+ }
+ _allFunctionsByName.remove(fdPrev.getName());
+ }
+ // check by name
+ fdPrev = _allFunctionsByName.get(funcName);
+ if(fdPrev != null) {
+ if(!fdPrev.hasFootnote() || !hasNote) {
+ throw new RuntimeException("changing function '"
+ + funcName + "' definition without foot-note");
+ }
+ _allFunctionsByIndex.remove(Integer.valueOf(fdPrev.getIndex()));
+ }
+ }
+
+ public void endTableGroup(String headingText) {
+ Integer[] keys = new Integer[_groupFunctionIndexes.size()];
+ _groupFunctionIndexes.toArray(keys);
+ _groupFunctionIndexes.clear();
+ _groupFunctionNames.clear();
+ Arrays.sort(keys);
+
+ _ps.println("# " + headingText);
+ for (Integer key : keys) {
+ FunctionData fd = _allFunctionsByIndex.get(key);
+ _ps.println(fd.formatAsDataLine());
+ }
+ }
+ }
+
+ private static final Pattern ID_MATCH = Pattern.compile("0x([\\dA-F]+)");
+ private static final Pattern NAME_MATCH = Pattern.compile("([0-9A-Z.]+)");
+ private static final Pattern ID_NAME_MATCH = Pattern.compile("0x([\\dA-F]+)\\s+([0-9A-Z.]+)");
+
+ private static final Set<String> IGNORED_LINES = new HashSet<>();
+ static {
+ IGNORED_LINES.add("[MS-XLS] â v20141018");
+ IGNORED_LINES.add("Excel Binary File Format (.xls) Structure");
+ IGNORED_LINES.add("Copyright © 2014 Microsoft Corporation.");
+ IGNORED_LINES.add("Release: October 30, 2014Value Meaning");
+ IGNORED_LINES.add("Release: October 30, 2014Value");
+ IGNORED_LINES.add("Meaning");
+ }
+
+ private static void extractFunctionData(FunctionDataCollector fdc, InputStream is) throws IOException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
+
+ String id = null;
+ String name = null;
+ while (true) {
+ String line = reader.readLine();
+ if(line == null) {
+ break;
+ }
+
+ if(IGNORED_LINES.contains(line) || line.matches("\\d+ / \\d+")) {
+ continue;
+ }
+
+ Matcher idMatcher = ID_MATCH.matcher(line);
+ boolean foundID = idMatcher.matches();
+ Matcher nameMatcher = NAME_MATCH.matcher(line);
+ boolean foundName = nameMatcher.matches();
+ Matcher idAndNameMatcher = ID_NAME_MATCH.matcher(line);
+ boolean foundIDandName = idAndNameMatcher.matches();
+ if(foundID && foundName ||
+ foundName && foundIDandName ||
+ foundID && foundIDandName) {
+ throw new IllegalStateException("Should not find id and name: " +
+ foundID + "/" + foundName + "/" + foundIDandName +
+ ", line: " + line);
+ }
+
+ if(foundID && id != null) {
+ throw new IllegalStateException("Found ID, but already had one: " + id + ", line: " + line);
+ }
+ if(foundName && name != null) {
+ throw new IllegalStateException("Found name, but already had one: " + name + ", line: " + line);
+ }
+ if(foundIDandName && (name != null || id != null)) {
+ throw new IllegalStateException("Found name and id, but already had one: id: " + id + ", name: " + name + ", line: " + line);
+ }
+
+ if(foundID) {
+ id = idMatcher.group(1);
+ } else if (foundName) {
+ name = nameMatcher.group(1);
+ } else if (foundIDandName) {
+ id = idAndNameMatcher.group(1);
+ name = idAndNameMatcher.group(2);
+ // manual override for one function name which contains lowercase characters
+ } else if(line.equals("VBAActivate")) {
+ name = line;
+ } else if (id == null || name == null) {
+ throw new IllegalStateException("Found params, but had empty id or name, id: " + id +
+ ", name: " + name + ", line: " + line);
+ } else {
+ System.out.println("Found function " + id + " " + name + " " + line);
+ fdc.addFunction(Integer.parseInt(id, 16), false, name, 0, 0,
+ "", "", "");
+
+ id = null;
+ name = null;
+ }
+ }
+ }
+
+ fdc.endTableGroup("");
+ }
+ /**
+ * To be sure that no tricky unicode chars make it through to the output file.
+ */
+ private static final class SimpleAsciiOutputStream extends OutputStream {
+
+ private final OutputStream _os;
+
+ public SimpleAsciiOutputStream(OutputStream os) {
+ _os = os;
+ }
+
+ @Override
public void write(int b) throws IOException {
- checkByte(b);
- _os.write(b);
- }
-
- private static void checkByte(int b) {
- if (!isSimpleAscii((char)b)) {
- throw new RuntimeException("Encountered char (" + b + ") which was not simple ascii as expected");
- }
- }
+ checkByte(b);
+ _os.write(b);
+ }
+
+ private static void checkByte(int b) {
+ if (!isSimpleAscii((char)b)) {
+ throw new RuntimeException("Encountered char (" + b + ") which was not simple ascii as expected");
+ }
+ }
- @Override
+ @Override
public void write(byte[] b, int off, int len) throws IOException {
- for (int i = 0; i < len; i++) {
- checkByte(b[i + off]);
+ for (int i = 0; i < len; i++) {
+ checkByte(b[i + off]);
- }
- _os.write(b, off, len);
- }
- }
-
- private static void processFile(InputStream input, File outFile) throws IOException {
- try (OutputStream os = new SimpleAsciiOutputStream(new FileOutputStream(outFile));
- PrintStream ps = new PrintStream(os, true, "UTF-8")) {
-
- outputLicenseHeader(ps);
- Class<?> genClass = ExcelCetabFunctionExtractor.class;
- ps.println("# Created by (" + genClass.getName() + ")");
- // identify the source file
- ps.println("# from source file '" + SOURCE_DOC_FILE_NAME + "'");
- ps.println("#");
- ps.println("#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )");
- ps.println();
- extractFunctionData(new FunctionDataCollector(ps), input);
- ps.close();
-
- String canonicalOutputFileName = outFile.getCanonicalPath();
- System.out.println("Successfully output to '" + canonicalOutputFileName + "'");
- }
- }
-
- private static void outputLicenseHeader(PrintStream ps) {
- String[] lines= {
- "Licensed to the Apache Software Foundation (ASF) under one or more",
- "contributor license agreements. See the NOTICE file distributed with",
- "this work for additional information regarding copyright ownership.",
- "The ASF licenses this file to You 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.",
- };
- for (String line : lines) {
- ps.print("# ");
- ps.println(line);
- }
- ps.println();
- }
-
- public static void main(String[] args) throws IOException {
- if(!new File(SOURCE_DOC_FILE_NAME).exists()) {
- throw new IllegalStateException("Did not find file " + SOURCE_DOC_FILE_NAME + " in the resources");
- }
-
- try (InputStream stream = new FileInputStream(SOURCE_DOC_FILE_NAME)) {
- File outFile = new File("functionMetadataCetab.txt");
-
- processFile(stream, outFile);
- }
- }
+ }
+ _os.write(b, off, len);
+ }
+ }
+
+ private static void processFile(InputStream input, File outFile) throws IOException {
+ try (OutputStream os = new SimpleAsciiOutputStream(new FileOutputStream(outFile));
+ PrintStream ps = new PrintStream(os, true, "UTF-8")) {
+
+ outputLicenseHeader(ps);
+ Class<?> genClass = ExcelCetabFunctionExtractor.class;
+ ps.println("# Created by (" + genClass.getName() + ")");
+ // identify the source file
+ ps.println("# from source file '" + SOURCE_DOC_FILE_NAME + "'");
+ ps.println("#");
+ ps.println("#Columns: (index, name, minParams, maxParams, returnClass, paramClasses, isVolatile, hasFootnote )");
+ ps.println();
+ extractFunctionData(new FunctionDataCollector(ps), input);
+ ps.close();
+
+ String canonicalOutputFileName = outFile.getCanonicalPath();
+ System.out.println("Successfully output to '" + canonicalOutputFileName + "'");
+ }
+ }
+
+ private static void outputLicenseHeader(PrintStream ps) {
+ String[] lines= {
+ "Licensed to the Apache Software Foundation (ASF) under one or more",
+ "contributor license agreements. See the NOTICE file distributed with",
+ "this work for additional information regarding copyright ownership.",
+ "The ASF licenses this file to You 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.",
+ };
+ for (String line : lines) {
+ ps.print("# ");
+ ps.println(line);
+ }
+ ps.println();
+ }
+
+ public static void main(String[] args) throws IOException {
+ if(!new File(SOURCE_DOC_FILE_NAME).exists()) {
+ throw new IllegalStateException("Did not find file " + SOURCE_DOC_FILE_NAME + " in the resources");
+ }
+
+ try (InputStream stream = new FileInputStream(SOURCE_DOC_FILE_NAME)) {
+ File outFile = new File("functionMetadataCetab.txt");
+
+ processFile(stream, outFile);
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org