aboutsummaryrefslogtreecommitdiffstats
path: root/poi
diff options
context:
space:
mode:
authorPJ Fanning <fanningpj@apache.org>2022-02-11 23:17:48 +0000
committerPJ Fanning <fanningpj@apache.org>2022-02-11 23:17:48 +0000
commitd9902ee89853ffb6c410bf188eb6e8fd53a7d179 (patch)
treef6b10d6271fd3fc69ef42e66190d47806124ed28 /poi
parent129c8513333444ddb61303f9758e59c3e9138825 (diff)
downloadpoi-d9902ee89853ffb6c410bf188eb6e8fd53a7d179.tar.gz
poi-d9902ee89853ffb6c410bf188eb6e8fd53a7d179.zip
add workday tests
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1897984 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poi')
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java14
-rw-r--r--poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java5
-rw-r--r--poi/src/test/java/org/apache/poi/ss/formula/atp/TestWorkdayIntlFunction.java247
3 files changed, 258 insertions, 8 deletions
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
index c9cdcb2853..67b20b3954 100644
--- a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
+++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
@@ -73,13 +73,13 @@ public class WorkdayCalculator {
weekendTypeMap.put(5, wedsThursWeekend);
weekendTypeMap.put(6, thursFriWeekend);
weekendTypeMap.put(7, friSatWeekend);
- weekendTypeMap.put(11, monWeekend);
- weekendTypeMap.put(12, tuesWeekend);
- weekendTypeMap.put(13, wedsWeekend);
- weekendTypeMap.put(14, thursWeekend);
- weekendTypeMap.put(15, friWeekend);
- weekendTypeMap.put(16, satWeekend);
- weekendTypeMap.put(17, sunWeekend);
+ weekendTypeMap.put(11, sunWeekend);
+ weekendTypeMap.put(12, monWeekend);
+ weekendTypeMap.put(13, tuesWeekend);
+ weekendTypeMap.put(14, wedsWeekend);
+ weekendTypeMap.put(15, thursWeekend);
+ weekendTypeMap.put(16, friWeekend);
+ weekendTypeMap.put(17, satWeekend);
}
/**
diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java
index 2e3b16b940..7067ccb266 100644
--- a/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java
+++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java
@@ -18,6 +18,7 @@
package org.apache.poi.ss.formula.atp;
import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
@@ -69,7 +70,9 @@ final class WorkdayIntlFunction implements FreeRefFunction {
start = this.evaluator.evaluateDateArg(args[0], srcCellRow, srcCellCol);
days = (int) Math.floor(this.evaluator.evaluateNumberArg(args[1], srcCellRow, srcCellCol));
if (args.length >= 3) {
- weekendType = (int) this.evaluator.evaluateNumberArg(args[2], srcCellRow, srcCellCol);
+ if (args[2] != BlankEval.instance) {
+ weekendType = (int) this.evaluator.evaluateNumberArg(args[2], srcCellRow, srcCellCol);
+ }
if (!WorkdayCalculator.instance.getValidWeekendTypes().contains(weekendType)) {
return ErrorEval.NUM_ERROR;
}
diff --git a/poi/src/test/java/org/apache/poi/ss/formula/atp/TestWorkdayIntlFunction.java b/poi/src/test/java/org/apache/poi/ss/formula/atp/TestWorkdayIntlFunction.java
new file mode 100644
index 0000000000..18e2c240a2
--- /dev/null
+++ b/poi/src/test/java/org/apache/poi/ss/formula/atp/TestWorkdayIntlFunction.java
@@ -0,0 +1,247 @@
+/* ====================================================================
+ 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.TwoDEval;
+import org.apache.poi.ss.formula.eval.AreaEval;
+import org.apache.poi.ss.formula.eval.AreaEvalBase;
+import org.apache.poi.ss.formula.eval.BlankEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.StringEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.util.LocaleUtil;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import static org.apache.poi.ss.formula.eval.ErrorEval.VALUE_INVALID;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class TestWorkdayIntlFunction {
+
+ private static final String STARTING_DATE = "2008/10/01";
+ private static final String FIRST_HOLIDAY = "2008/11/26";
+ private static final String SECOND_HOLIDAY = "2008/12/04";
+ private static final String THIRD_HOLIDAY = "2009/01/21";
+ private static final String RETROATIVE_HOLIDAY = "2008/09/29";
+
+ private static final OperationEvaluationContext EC = new OperationEvaluationContext(null, null, 1, 1, 1, null);
+
+ @Test
+ void testFailWhenNoArguments() {
+ ValueEval[] ve = new ValueEval[0];
+ assertEquals(VALUE_INVALID, WorkdayIntlFunction.instance.evaluate(ve, null));
+ }
+
+ @Test
+ void testFailWhenLessThan2Arguments() {
+ ValueEval[] ve = new ValueEval[1];
+ assertEquals(VALUE_INVALID, WorkdayIntlFunction.instance.evaluate(ve, null));
+ }
+
+ @Test
+ void testFailWhenMoreThan4Arguments() {
+ ValueEval[] ve = new ValueEval[5];
+ assertEquals(VALUE_INVALID, WorkdayIntlFunction.instance.evaluate(ve, null));
+ }
+
+ @Test
+ void testFailWhenArgumentsAreNotDatesNorNumbers() {
+ ValueEval[] ve = {new StringEval("Potato"), new StringEval("Cucumber")};
+ assertEquals(VALUE_INVALID, WorkdayIntlFunction.instance.evaluate(ve, EC));
+ }
+
+ @Test
+ void testReturnWorkdays() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2009, 3, 30);
+ Date expDate = expCal.getTime();
+ ValueEval[] ve = {new StringEval(STARTING_DATE), new NumberEval(151)};
+ Date actDate = DateUtil.getJavaDate(((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue());
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnWorkdaysSpanningAWeekendSubtractingDays() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 8, 27);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {new StringEval("2013/09/30"), new NumberEval(-1)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+ assertEquals(41544.0, numberValue, 0);
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnWorkdaysSpanningAWeekendAddingDays() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 8, 30);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {new StringEval("2013/09/27"), new NumberEval(1)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+ assertEquals(41547.0, numberValue, 0);
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnWorkdaysWhenStartIsWeekendAddingDays() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 9, 7);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {new StringEval("2013/10/06"), new NumberEval(1)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+ assertEquals(41554.0, numberValue, 0);
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnWorkdaysWhenStartIsWeekendSubtractingDays() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2013, 9, 4);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {new StringEval("2013/10/06"), new NumberEval(-1)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+ assertEquals(41551.0, numberValue, 0);
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnWorkdaysWithDaysTruncated() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2009, 3, 30);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {new StringEval(STARTING_DATE), new NumberEval(151.99999)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnRetroativeWorkday() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2008, 8, 23);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {new StringEval(STARTING_DATE), new NumberEval(-5),
+ BlankEval.instance, new StringEval(RETROATIVE_HOLIDAY)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testReturnNetworkdaysWithManyHolidays() {
+ Calendar expCal = LocaleUtil.getLocaleCalendar(2009, 4, 5);
+ Date expDate = expCal.getTime();
+
+ ValueEval[] ve = {
+ new StringEval(STARTING_DATE), new NumberEval(151), BlankEval.instance,
+ new MockAreaEval(FIRST_HOLIDAY, SECOND_HOLIDAY, THIRD_HOLIDAY)};
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+
+ Date actDate = DateUtil.getJavaDate(numberValue);
+ assertEquals(expDate, actDate);
+ }
+
+ @Test
+ void testMicrosoftExample1() {
+ final String testDate = "2012-01-01";
+ ValueEval[] ve = {
+ new StringEval(testDate), new NumberEval(30), new NumberEval(0)
+ };
+ assertEquals(ErrorEval.NUM_ERROR, WorkdayIntlFunction.instance.evaluate(ve, EC));
+ }
+
+ @Test
+ void testMicrosoftExample2() {
+ final String testDate = "2012-01-01";
+ ValueEval[] ve = {
+ new StringEval(testDate), new NumberEval(90), new NumberEval(11)
+ };
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+ assertEquals(41013.0, numberValue);
+ }
+
+ @Test
+ void testMicrosoftExample3() {
+ final String testDate = "2012-01-01";
+ ValueEval[] ve = {
+ new StringEval(testDate), new NumberEval(30), new NumberEval(17)
+ };
+ double numberValue = ((NumberEval) WorkdayIntlFunction.instance.evaluate(ve, EC)).getNumberValue();
+ assertEquals(40944.0, numberValue);
+ }
+
+ private class MockAreaEval extends AreaEvalBase {
+
+ private List<ValueEval> holidays;
+
+ public MockAreaEval(String... holidays) {
+ this(0, 0, 0, holidays.length - 1);
+ this.holidays = new ArrayList<>();
+ for (String holiday : holidays) {
+ this.holidays.add(new StringEval(holiday));
+ }
+ }
+
+ protected MockAreaEval(int firstRow, int firstColumn, int lastRow, int lastColumn) {
+ super(firstRow, firstColumn, lastRow, lastColumn);
+ }
+
+ @Override
+ public ValueEval getRelativeValue(int sheetIndex, int relativeRowIndex, int relativeColumnIndex) {
+ return this.holidays.get(relativeColumnIndex);
+ }
+ @Override
+ public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
+ return getRelativeValue(-1, relativeRowIndex, relativeColumnIndex);
+ }
+
+ @Override
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ return null;
+ }
+
+ @Override
+ public TwoDEval getColumn(int columnIndex) {
+ return null;
+ }
+
+ @Override
+ public TwoDEval getRow(int rowIndex) {
+ return null;
+ }
+
+ }
+}