/* * ==================================================================== * 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 junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.formula.eval.NumberEval; import org.apache.poi.ss.formula.eval.ValueEval; /** * Test for Excel function INTERCEPT() * * @author Johan Karlsteen */ public final class TestIntercept extends TestCase { private static final Function INTERCEPT = new Intercept(); private static ValueEval invoke(Function function, ValueEval xArray, ValueEval yArray) { ValueEval[] args = new ValueEval[] { xArray, yArray, }; return function.evaluate(args, -1, (short)-1); } private void confirm(Function function, ValueEval xArray, ValueEval yArray, double expected) { ValueEval result = invoke(function, xArray, yArray); assertEquals(NumberEval.class, result.getClass()); assertEquals(expected, ((NumberEval)result).getNumberValue(), 0); } private void confirmError(Function function, ValueEval xArray, ValueEval yArray, ErrorEval expectedError) { ValueEval result = invoke(function, xArray, yArray); assertEquals(ErrorEval.class, result.getClass()); assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode()); } private void confirmError(ValueEval xArray, ValueEval yArray, ErrorEval expectedError) { confirmError(INTERCEPT, xArray, yArray, expectedError); } public void testBasic() { Double exp = Math.pow(10, 7.5); ValueEval[] yValues = { new NumberEval(3+exp), new NumberEval(4+exp), new NumberEval(2+exp), new NumberEval(5+exp), new NumberEval(4+exp), new NumberEval(7+exp), }; ValueEval areaEvalY = createAreaEval(yValues); ValueEval[] xValues = { new NumberEval(1), new NumberEval(2), new NumberEval(3), new NumberEval(4), new NumberEval(5), new NumberEval(6), }; ValueEval areaEvalX = createAreaEval(xValues); confirm(INTERCEPT, areaEvalX, areaEvalY, -24516534.39905822); // Excel 2010 gives -24516534.3990583 } /** * number of items in array is not limited to 30 */ public void testLargeArrays() { ValueEval[] yValues = createMockNumberArray(100, 3); // [1,2,0,1,2,0,...,0,1] yValues[0] = new NumberEval(2.0); // Changes first element to 2 ValueEval[] xValues = createMockNumberArray(100, 101); // [1,2,3,4,...,99,100] confirm(INTERCEPT, createAreaEval(xValues), createAreaEval(yValues), 51.74384236453202); // Excel 2010 gives 51.74384236453200 } private ValueEval[] createMockNumberArray(int size, double value) { ValueEval[] result = new ValueEval[size]; for (int i = 0; i < result.length; i++) { result[i] = new NumberEval((i+1)%value); } return result; } private static ValueEval createAreaEval(ValueEval[] values) { String refStr = "A1:A" + values.length; return EvalFactory.createAreaEval(refStr, values); } public void testErrors() { ValueEval[] xValues = { ErrorEval.REF_INVALID, new NumberEval(2), }; ValueEval areaEvalX = createAreaEval(xValues); ValueEval[] yValues = { new NumberEval(2), ErrorEval.NULL_INTERSECTION, }; ValueEval areaEvalY = createAreaEval(yValues); ValueEval[] zValues = { // wrong size new NumberEval(2), }; ValueEval areaEvalZ = createAreaEval(zValues); // if either arg is an error, that error propagates confirmError(ErrorEval.REF_INVALID, ErrorEval.NAME_INVALID, ErrorEval.REF_INVALID); confirmError(areaEvalX, ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID); confirmError(ErrorEval.NAME_INVALID, areaEvalX, ErrorEval.NAME_INVALID); // array sizes must match confirmError(areaEvalX, areaEvalZ, ErrorEval.NA); confirmError(areaEvalZ, areaEvalY, ErrorEval.NA); // any error in an array item propagates up confirmError(areaEvalX, areaEvalX, ErrorEval.REF_INVALID); // search for errors array by array, not pair by pair confirmError(areaEvalX, areaEvalY, ErrorEval.NULL_INTERSECTION); confirmError(areaEvalY, areaEvalX, ErrorEval.REF_INVALID); } /** * Example from * http://office.microsoft.com/en-us/excel-help/intercept-function-HP010062512.aspx?CTT=5&origin=HA010277524 */ public void testFromFile() { HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("intercept.xls"); HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb); HSSFSheet example1 = wb.getSheet("Example 1"); HSSFCell a8 = example1.getRow(7).getCell(0); assertEquals("INTERCEPT(A2:A6,B2:B6)", a8.getCellFormula()); fe.evaluate(a8); assertEquals(0.048387097, a8.getNumericCellValue(), 0.000000001); } }