You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.ss.formula.functions;
  20. import junit.framework.TestCase;
  21. import org.apache.poi.hssf.HSSFTestDataSamples;
  22. import org.apache.poi.hssf.usermodel.HSSFCell;
  23. import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
  24. import org.apache.poi.hssf.usermodel.HSSFSheet;
  25. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  26. import org.apache.poi.ss.formula.eval.ErrorEval;
  27. import org.apache.poi.ss.formula.eval.NumberEval;
  28. import org.apache.poi.ss.formula.eval.ValueEval;
  29. /**
  30. * Test for Excel function INTERCEPT()
  31. *
  32. * @author Johan Karlsteen
  33. */
  34. public final class TestIntercept extends TestCase {
  35. private static final Function INTERCEPT = new Intercept();
  36. private static ValueEval invoke(Function function, ValueEval xArray, ValueEval yArray) {
  37. ValueEval[] args = new ValueEval[] { xArray, yArray, };
  38. return function.evaluate(args, -1, (short)-1);
  39. }
  40. private void confirm(Function function, ValueEval xArray, ValueEval yArray, double expected) {
  41. ValueEval result = invoke(function, xArray, yArray);
  42. assertEquals(NumberEval.class, result.getClass());
  43. assertEquals(expected, ((NumberEval)result).getNumberValue(), 0);
  44. }
  45. private void confirmError(Function function, ValueEval xArray, ValueEval yArray, ErrorEval expectedError) {
  46. ValueEval result = invoke(function, xArray, yArray);
  47. assertEquals(ErrorEval.class, result.getClass());
  48. assertEquals(expectedError.getErrorCode(), ((ErrorEval)result).getErrorCode());
  49. }
  50. private void confirmError(ValueEval xArray, ValueEval yArray, ErrorEval expectedError) {
  51. confirmError(INTERCEPT, xArray, yArray, expectedError);
  52. }
  53. public void testBasic() {
  54. Double exp = Math.pow(10, 7.5);
  55. ValueEval[] xValues = {
  56. new NumberEval(3+exp),
  57. new NumberEval(4+exp),
  58. new NumberEval(2+exp),
  59. new NumberEval(5+exp),
  60. new NumberEval(4+exp),
  61. new NumberEval(7+exp),
  62. };
  63. ValueEval areaEvalX = createAreaEval(xValues);
  64. ValueEval[] yValues = {
  65. new NumberEval(1),
  66. new NumberEval(2),
  67. new NumberEval(3),
  68. new NumberEval(4),
  69. new NumberEval(5),
  70. new NumberEval(6),
  71. };
  72. ValueEval areaEvalY = createAreaEval(yValues);
  73. confirm(INTERCEPT, areaEvalX, areaEvalY, -24516534.39905822);
  74. // Excel 2010 gives -24516534.3990583
  75. }
  76. /**
  77. * number of items in array is not limited to 30
  78. */
  79. public void testLargeArrays() {
  80. ValueEval[] xValues = createMockNumberArray(100, 3); // [1,2,0,1,2,0,...,0,1]
  81. xValues[0] = new NumberEval(2.0); // Changes first element to 2
  82. ValueEval[] yValues = createMockNumberArray(100, 101); // [1,2,3,4,...,99,100]
  83. confirm(INTERCEPT, createAreaEval(xValues), createAreaEval(yValues), 51.74384236453202);
  84. // Excel 2010 gives 51.74384236453200
  85. }
  86. private ValueEval[] createMockNumberArray(int size, double value) {
  87. ValueEval[] result = new ValueEval[size];
  88. for (int i = 0; i < result.length; i++) {
  89. result[i] = new NumberEval((i+1)%value);
  90. }
  91. return result;
  92. }
  93. private static ValueEval createAreaEval(ValueEval[] values) {
  94. String refStr = "A1:A" + values.length;
  95. return EvalFactory.createAreaEval(refStr, values);
  96. }
  97. public void testErrors() {
  98. ValueEval[] xValues = {
  99. ErrorEval.REF_INVALID,
  100. new NumberEval(2),
  101. };
  102. ValueEval areaEvalX = createAreaEval(xValues);
  103. ValueEval[] yValues = {
  104. new NumberEval(2),
  105. ErrorEval.NULL_INTERSECTION,
  106. };
  107. ValueEval areaEvalY = createAreaEval(yValues);
  108. ValueEval[] zValues = { // wrong size
  109. new NumberEval(2),
  110. };
  111. ValueEval areaEvalZ = createAreaEval(zValues);
  112. // if either arg is an error, that error propagates
  113. confirmError(ErrorEval.REF_INVALID, ErrorEval.NAME_INVALID, ErrorEval.REF_INVALID);
  114. confirmError(areaEvalX, ErrorEval.NAME_INVALID, ErrorEval.NAME_INVALID);
  115. confirmError(ErrorEval.NAME_INVALID, areaEvalX, ErrorEval.NAME_INVALID);
  116. // array sizes must match
  117. confirmError(areaEvalX, areaEvalZ, ErrorEval.NA);
  118. confirmError(areaEvalZ, areaEvalY, ErrorEval.NA);
  119. // any error in an array item propagates up
  120. confirmError(areaEvalX, areaEvalX, ErrorEval.REF_INVALID);
  121. // search for errors array by array, not pair by pair
  122. confirmError(areaEvalX, areaEvalY, ErrorEval.REF_INVALID);
  123. confirmError(areaEvalY, areaEvalX, ErrorEval.NULL_INTERSECTION);
  124. }
  125. /**
  126. * Example from
  127. * http://office.microsoft.com/en-us/excel-help/intercept-function-HP010062512.aspx?CTT=5&origin=HA010277524
  128. */
  129. public void testFromFile() {
  130. HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("intercept.xls");
  131. HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
  132. HSSFSheet example1 = wb.getSheet("Example 1");
  133. HSSFCell a8 = example1.getRow(7).getCell(0);
  134. assertEquals("INTERCEPT(A2:A6,B2:B6)", a8.getCellFormula());
  135. fe.evaluate(a8);
  136. assertEquals(0.048387097, a8.getNumericCellValue(), 0.000000001);
  137. }
  138. }