git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1891876 13f79535-47bb-0310-9956-ffa450edef68tags/REL_5_1_0
@@ -80,7 +80,7 @@ public final class AnalysisToolPak implements UDFFinder { | |||
} | |||
private Map<String, FreeRefFunction> createFunctionsMap() { | |||
Map<String, FreeRefFunction> m = new HashMap<>(108); | |||
Map<String, FreeRefFunction> m = new HashMap<>(127); | |||
r(m, "ACCRINT", null); | |||
r(m, "ACCRINTM", null); | |||
@@ -136,6 +136,7 @@ public final class AnalysisToolPak implements UDFFinder { | |||
r(m, "HEX2DEC", Hex2Dec.instance); | |||
r(m, "HEX2OCT", null); | |||
r(m, "IFERROR", IfError.instance); | |||
r(m, "IFNA", IfNa.instance); | |||
r(m, "IFS", Ifs.instance); | |||
r(m, "IMABS", null); | |||
r(m, "IMAGINARY", Imaginary.instance); | |||
@@ -260,7 +261,7 @@ public final class AnalysisToolPak implements UDFFinder { | |||
FunctionMetadata metaData = FunctionMetadataRegistry.getFunctionByName(name); | |||
if(metaData != null) { | |||
throw new IllegalArgumentException(name + " is a built-in Excel function. " + | |||
"Use FunctoinEval.registerFunction(String name, Function func) instead."); | |||
"Use FunctionEval.registerFunction(String name, Function func) instead."); | |||
} | |||
throw new IllegalArgumentException(name + " is not a function from the Excel Analysis Toolpack."); |
@@ -0,0 +1,65 @@ | |||
/* ==================================================================== | |||
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. | |||
==================================================================== */ | |||
package org.apache.poi.ss.formula.atp; | |||
import org.apache.poi.ss.formula.OperationEvaluationContext; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
import org.apache.poi.ss.formula.eval.EvaluationException; | |||
import org.apache.poi.ss.formula.eval.OperandResolver; | |||
import org.apache.poi.ss.formula.eval.ValueEval; | |||
import org.apache.poi.ss.formula.functions.FreeRefFunction; | |||
/** | |||
* Implementation of 'Analysis Toolpak' the Excel function IFNA() | |||
* | |||
* <b>Syntax</b>:<br> | |||
* <b>IFNA</b>(<b>test_value</b>,<b>default_value</b>)<p> | |||
* | |||
* <b>test_value</b> The value to be tested<br> | |||
* <b>default_value</b> The value to be tested<br> | |||
* <br> | |||
* Returns {@code default_value} if {@code test_value} is '#N/A', {@code test_value} otherwise. | |||
*/ | |||
public final class IfNa implements FreeRefFunction { | |||
public static final FreeRefFunction instance = new IfNa(); | |||
private IfNa() { | |||
// Enforce singleton | |||
} | |||
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) { | |||
if (args.length != 2) { | |||
return ErrorEval.VALUE_INVALID; | |||
} | |||
try { | |||
return OperandResolver.getSingleValue(args[0], ec.getRowIndex(), ec.getColumnIndex()); | |||
} catch (EvaluationException e) { | |||
ValueEval error = e.getErrorEval(); | |||
if (error != ErrorEval.NA) { | |||
return error; | |||
} | |||
} | |||
try { | |||
return OperandResolver.getSingleValue(args[1], ec.getRowIndex(), ec.getColumnIndex()); | |||
} catch (EvaluationException e) { | |||
return e.getErrorEval(); | |||
} | |||
} | |||
} |
@@ -163,7 +163,7 @@ class TestFunctionRegistry { | |||
() -> AnalysisToolPak.registerFunction("SUM", TestFunctionRegistry::atpFunc) | |||
); | |||
assertEquals("SUM is a built-in Excel function. " + | |||
"Use FunctoinEval.registerFunction(String name, Function func) instead.", | |||
"Use FunctionEval.registerFunction(String name, Function func) instead.", | |||
ex.getMessage()); | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
/* ==================================================================== | |||
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. | |||
==================================================================== */ | |||
package org.apache.poi.ss.formula.atp; | |||
import static org.junit.jupiter.api.Assertions.assertEquals; | |||
import org.apache.poi.hssf.usermodel.HSSFCell; | |||
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; | |||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
import org.apache.poi.ss.formula.eval.ErrorEval; | |||
import org.apache.poi.ss.usermodel.CellType; | |||
import org.apache.poi.ss.usermodel.CellValue; | |||
import org.junit.jupiter.api.Test; | |||
import org.junit.jupiter.api.BeforeEach; | |||
/** | |||
* IfNa unit tests. | |||
*/ | |||
class TestIfna { | |||
HSSFWorkbook wb; | |||
HSSFCell cell; | |||
HSSFFormulaEvaluator fe; | |||
@BeforeEach | |||
void setup() { | |||
wb = new HSSFWorkbook(); | |||
cell = wb.createSheet().createRow(0).createCell(0); | |||
fe = new HSSFFormulaEvaluator(wb); | |||
} | |||
@Test | |||
void testNumbericArgsWorkCorrectly() { | |||
confirmResult(fe, cell, "IFNA(-1,42)", new CellValue(-1.0)); | |||
confirmResult(fe, cell, "IFNA(NA(),42)", new CellValue(42.0)); | |||
} | |||
@Test | |||
void testStringArgsWorkCorrectly() { | |||
confirmResult(fe, cell, "IFNA(\"a1\",\"a2\")", new CellValue("a1")); | |||
confirmResult(fe, cell, "IFNA(NA(),\"a2\")", new CellValue("a2")); | |||
} | |||
@Test | |||
void testUsageErrorsThrowErrors() { | |||
confirmError(fe, cell, "IFNA(1)", ErrorEval.VALUE_INVALID); | |||
confirmError(fe, cell, "IFNA(1,2,3)", ErrorEval.VALUE_INVALID); | |||
} | |||
@Test | |||
void testErrorInArgSelectsNAResult() { | |||
confirmError(fe, cell, "IFNA(1/0,42)", ErrorEval.DIV_ZERO); | |||
} | |||
@Test | |||
void testErrorFromNAArgPassesThrough() { | |||
confirmError(fe, cell, "IFNA(NA(),1/0)", ErrorEval.DIV_ZERO); | |||
} | |||
@Test | |||
void testNaArgNotEvaledIfUnneeded() { | |||
confirmResult(fe, cell, "IFNA(42,1/0)", new CellValue(42.0)); | |||
} | |||
private static void confirmResult(HSSFFormulaEvaluator fe, HSSFCell cell, String formulaText, | |||
CellValue expectedResult) { | |||
fe.setDebugEvaluationOutputForNextEval(true); | |||
cell.setCellFormula(formulaText); | |||
fe.notifyUpdateCell(cell); | |||
CellValue result = fe.evaluate(cell); | |||
assertEquals(expectedResult.getCellType(), result.getCellType(), "Testing result type for: " + formulaText); | |||
assertEquals(expectedResult.formatAsString(), result.formatAsString(), "Testing result for: " + formulaText); | |||
} | |||
private static void confirmError(HSSFFormulaEvaluator fe, HSSFCell cell, String formulaText, | |||
ErrorEval expectedError) { | |||
fe.setDebugEvaluationOutputForNextEval(true); | |||
cell.setCellFormula(formulaText); | |||
fe.notifyUpdateCell(cell); | |||
CellValue result = fe.evaluate(cell); | |||
assertEquals(CellType.ERROR, result.getCellType(), "Testing result type for: " + formulaText); | |||
assertEquals(expectedError.getErrorString(), result.formatAsString(), "Testing error type for: " + formulaText); | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
/* ==================================================================== | |||
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. | |||
==================================================================== */ | |||
package org.apache.poi.ss.formula.functions; | |||
import java.util.stream.Stream; | |||
import org.junit.jupiter.params.provider.Arguments; | |||
/** | |||
* Tests for IFNA function as loaded from a test data spreadsheet.<p> | |||
*/ | |||
class TestIfnaFromSpreadsheet extends BaseTestFunctionsFromSpreadsheet { | |||
public static Stream<Arguments> data() throws Exception { | |||
return data(TestIfnaFromSpreadsheet.class, "IfNaTestCaseData.xls"); | |||
} | |||
} |