]> source.dussan.org Git - poi.git/commitdiff
add workday tests
authorPJ Fanning <fanningpj@apache.org>
Fri, 11 Feb 2022 23:17:48 +0000 (23:17 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 11 Feb 2022 23:17:48 +0000 (23:17 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1897984 13f79535-47bb-0310-9956-ffa450edef68

poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayCalculator.java
poi/src/main/java/org/apache/poi/ss/formula/atp/WorkdayIntlFunction.java
poi/src/test/java/org/apache/poi/ss/formula/atp/TestWorkdayIntlFunction.java [new file with mode: 0644]

index c9cdcb2853b53e90486bff044ea11edf75036a5c..67b20b39544cf47b282caa9738e100bf2109f3e3 100644 (file)
@@ -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);
     }
 
     /**
index 2e3b16b9403112cb0f09faccce4a2fc2917dc8b9..7067ccb266ba04a4124d0db73df20336fc4e64b1 100644 (file)
@@ -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 (file)
index 0000000..18e2c24
--- /dev/null
@@ -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;
+        }
+
+    }
+}