/* * Copyright (c) 2017 OBiBa. All rights reserved. * * This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.obiba.magma.js.methods; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import org.junit.Test; import org.mozilla.javascript.Context; import org.obiba.magma.Value; import org.obiba.magma.ValueSequence; import org.obiba.magma.ValueType; import org.obiba.magma.js.AbstractJsTest; import org.obiba.magma.js.ScriptableValue; import org.obiba.magma.type.BooleanType; import org.obiba.magma.type.DateTimeType; import org.obiba.magma.type.DateType; import org.obiba.magma.type.IntegerType; import org.obiba.magma.type.TextType; import com.google.common.collect.ImmutableList; import static org.fest.assertions.api.Assertions.assertThat; @SuppressWarnings({ "ReuseOfLocalVariable" }) public class DateTimeMethodTest extends AbstractJsTest { @Test public void test_year_acceptsDateTime() { testCalendarFieldMethod("year()", Calendar.YEAR, DateTimeType.get()); } @Test public void test_year_acceptsDate() { testCalendarFieldMethod("year()", Calendar.YEAR, DateType.get()); } @Test public void test_month_acceptsDateTime() { testCalendarFieldMethod("month()", Calendar.MONTH, DateTimeType.get()); } @Test public void test_month_acceptsDate() { testCalendarFieldMethod("month()", Calendar.MONTH, DateType.get()); } @Test public void test_quarter() { Calendar calendar = Calendar.getInstance(); for(int i = 0; i < 12; i++) { int q = i / 3; calendar.set(Calendar.MONTH, i); ScriptableValue result = evaluate("quarter()", DateType.get().valueOf(calendar)); assertIntegerResult(result, q, false); result = evaluate("quarter()", DateTimeType.get().valueOf(calendar)); assertIntegerResult(result, q, false); } } @Test public void test_quarter_acceptsNull() { ScriptableValue value = evaluate("quarter()", DateType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(IntegerType.get().nullValue()); value = evaluate("quarter()", DateTimeType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(IntegerType.get().nullValue()); } @Test public void test_semester() { Calendar calendar = Calendar.getInstance(); for(int i = 0; i < 12; i++) { int s = i / 6; calendar.set(Calendar.MONTH, i); ScriptableValue result = evaluate("semester()", DateType.get().valueOf(calendar)); assertIntegerResult(result, s, false); result = evaluate("semester()", DateTimeType.get().valueOf(calendar)); assertIntegerResult(result, s, false); } } @Test public void test_semester_sequence() { Calendar calendar = Calendar.getInstance(); Collection<Value> values = new ArrayList<>(); for(int i = 0; i < 12; i++) { calendar.set(Calendar.MONTH, i); values.add(DateType.get().valueOf(calendar)); } ScriptableValue result = evaluate("semester()", DateType.get().sequenceOf(values)); assertThat(result.getValue().isSequence()).isTrue(); } @Test public void test_semester_acceptsNull() { ScriptableValue value = evaluate("semester()", DateType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(IntegerType.get().nullValue()); value = evaluate("semester()", DateTimeType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(IntegerType.get().nullValue()); } @Test public void test_semester_acceptsNullSequence() { ScriptableValue value = evaluate("semester()", DateType.get().nullSequence()); assertThat(value).isNotNull(); assertThat(value.getValue().isNull()).isTrue(); assertThat(value.getValue().isSequence()).isTrue(); assertThat(value.getValue().asSequence()).isEqualTo(IntegerType.get().nullSequence()); value = evaluate("semester()", DateTimeType.get().nullSequence()); assertThat(value).isNotNull(); assertThat(value.getValue().isNull()).isTrue(); assertThat(value.getValue().isSequence()).isTrue(); assertThat(value.getValue().asSequence()).isEqualTo(IntegerType.get().nullSequence()); } @Test public void test_dayOfMonth_acceptsDateTime() { testCalendarFieldMethod("dayOfMonth()", Calendar.DAY_OF_MONTH, DateTimeType.get()); } @Test public void test_dayOfMonth_acceptsDate() { testCalendarFieldMethod("dayOfMonth()", Calendar.DAY_OF_MONTH, DateType.get()); } @Test public void test_dayOfWeek_acceptsDateTime() { testCalendarFieldMethod("dayOfWeek()", Calendar.DAY_OF_WEEK, DateTimeType.get()); } @Test public void test_dayOfWeek_acceptsDate() { testCalendarFieldMethod("dayOfWeek()", Calendar.DAY_OF_WEEK, DateType.get()); } @Test public void test_dayOfYear_acceptsDateTime() { testCalendarFieldMethod("dayOfYear()", Calendar.DAY_OF_YEAR, DateTimeType.get()); } @Test public void test_dayOfYear_acceptsDate() { testCalendarFieldMethod("dayOfYear()", Calendar.DAY_OF_YEAR, DateType.get()); } @Test public void test_weekend() { testWeekendOrWeekdayMethod("weekend()", Calendar.SATURDAY, true); testWeekendOrWeekdayMethod("weekend()", Calendar.SUNDAY, true); testWeekendOrWeekdayMethod("weekend()", Calendar.MONDAY, false); testWeekendOrWeekdayMethod("weekend()", Calendar.TUESDAY, false); testWeekendOrWeekdayMethod("weekend()", Calendar.WEDNESDAY, false); testWeekendOrWeekdayMethod("weekend()", Calendar.THURSDAY, false); testWeekendOrWeekdayMethod("weekend()", Calendar.FRIDAY, false); } @Test public void test_weekend_acceptsNull() { ScriptableValue value = evaluate("weekend()", DateType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().nullValue()); value = evaluate("weekend()", DateTimeType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().nullValue()); } @Test public void test_weekday() { testWeekendOrWeekdayMethod("weekday()", Calendar.SATURDAY, false); testWeekendOrWeekdayMethod("weekday()", Calendar.SUNDAY, false); testWeekendOrWeekdayMethod("weekday()", Calendar.MONDAY, true); testWeekendOrWeekdayMethod("weekday()", Calendar.TUESDAY, true); testWeekendOrWeekdayMethod("weekday()", Calendar.WEDNESDAY, true); testWeekendOrWeekdayMethod("weekday()", Calendar.THURSDAY, true); testWeekendOrWeekdayMethod("weekday()", Calendar.FRIDAY, true); } @Test public void test_weekday_acceptsNull() { ScriptableValue value = evaluate("weekday()", DateType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().nullValue()); value = evaluate("weekday()", DateTimeType.get().nullValue()); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().nullValue()); } @Test public void test_weekOfYear_acceptsDateTime() { testCalendarFieldMethod("weekOfYear()", Calendar.WEEK_OF_YEAR, DateTimeType.get()); } @Test public void test_weekOfYear_acceptsDate() { testCalendarFieldMethod("weekOfYear()", Calendar.WEEK_OF_YEAR, DateType.get()); } @Test public void test_weekOfMonth_acceptsDateTime() { testCalendarFieldMethod("weekOfMonth()", Calendar.WEEK_OF_MONTH, DateTimeType.get()); } @Test public void test_weekOfMonth_acceptsDate() { testCalendarFieldMethod("weekOfMonth()", Calendar.WEEK_OF_MONTH, DateType.get()); } @Test public void test_hourOfDay_acceptsDateTime() { testCalendarFieldMethod("hourOfDay()", Calendar.HOUR_OF_DAY, DateTimeType.get()); } @Test public void test_hour_acceptsDateTime() { testCalendarFieldMethod("hour()", Calendar.HOUR, DateTimeType.get()); } @Test public void test_minute_acceptsDateTime() { testCalendarFieldMethod("minute()", Calendar.MINUTE, DateTimeType.get()); } @Test public void test_second_acceptsDateTime() { testCalendarFieldMethod("second()", Calendar.SECOND, DateTimeType.get()); } @Test public void test_millisecond_acceptsDateTime() { testCalendarFieldMethod("millisecond()", Calendar.MILLISECOND, DateTimeType.get()); } @Test public void test_format_acceptsDateTime() { testFormatMethod("dd/MM/yyyy HH:mm", DateTimeType.get()); } @Test public void test_format_acceptsDate() { testFormatMethod("dd/MM/yyyy", DateType.get()); } @Test public void test_format_acceptsNULLDateNULL() { ScriptableValue value = newValue(DateType.get().nullValue()); ScriptableValue result = evaluate("format()", value.getValue()); assertThat(result.getValue()).isEqualTo(TextType.get().nullValue()); } @Test public void testAfterNullArgumentReturnsNull() throws Exception { ScriptableValue now = newValue(DateTimeType.get().valueOf(new Date())); ScriptableValue nullDate = newValue(DateTimeType.get().nullValue()); ScriptableValue result = (ScriptableValue) DateTimeMethods .after(Context.getCurrentContext(), now, new ScriptableValue[] { nullDate }, null); assertThat(result).isNotNull(); assertThat(result.getValue()).isEqualTo(BooleanType.get().nullValue()); } @Test public void testAfterNullCallerReturnsNull() throws Exception { ScriptableValue now = newValue(DateTimeType.get().valueOf(new Date())); ScriptableValue nullDate = newValue(DateTimeType.get().nullValue()); ScriptableValue result = (ScriptableValue) DateTimeMethods .after(Context.getCurrentContext(), nullDate, new ScriptableValue[] { now }, null); assertThat(result).isNotNull(); assertThat(result.getValue()).isEqualTo(BooleanType.get().nullValue()); } @Test public void test_after() throws Exception { ScriptableValue value = evaluate("after(newValue('2011-11-01', 'date'))", DateType.get().valueOf(new Date())); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().trueValue()); value = evaluate("after(newValue('2011-11-01', 'date'), newValue('2011-11-01T10:00:00-0000', 'datetime'))", DateType.get().valueOf(new Date())); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().trueValue()); } private Value makeDayOfWeek(ValueType valueType, int dayOfWeek) { Calendar calendar = Calendar.getInstance(); while(calendar.get(Calendar.DAY_OF_WEEK) != dayOfWeek) { calendar.add(Calendar.DAY_OF_WEEK, 1); } return valueType.valueOf(calendar); } private void testWeekendOrWeekdayMethod(String script, int dayOfWeek, boolean expected) { ScriptableValue value = evaluate(script, makeDayOfWeek(DateType.get(), dayOfWeek)); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().valueOf(expected)); value = evaluate(script, makeDayOfWeek(DateTimeType.get(), dayOfWeek)); assertThat(value).isNotNull(); assertThat(value.getValue()).isEqualTo(BooleanType.get().valueOf(expected)); } /** * Executes {@code script} with {@code testValue} as its scope and asserts that the returned value is * * @param script * @param field * @param testValue */ private void testCalendarFieldMethod(String script, int field, ValueType testType) { Calendar testValue = Calendar.getInstance(); ScriptableValue result = evaluate(script, testType.valueOf(testValue)); assertIntegerResult(result, testValue.get(field), false); result = evaluate(script, testType.sequenceOf(ImmutableList.of(testType.valueOf(testValue)))); assertIntegerResult(result, testValue.get(field), true); } private void assertIntegerResult(ScriptableValue result, int expectedValue, boolean sequence) { assertThat(result).isNotNull(); assertThat(result.getValue()).isNotNull(); assertThat(result.getValueType()).isEqualTo(IntegerType.get()); assertThat(result.getValue().isSequence()).isEqualTo(sequence); if(sequence) { ValueSequence seq = result.getValue().asSequence(); assertThat(seq.getSize()).isEqualTo(1); assertThat((Long) seq.get(0).getValue()).isEqualTo((long) expectedValue); } else { assertThat((Long) result.getValue().getValue()).isEqualTo((long) expectedValue); } } private void testFormatMethod(String pattern, ValueType testType) { Date now = new Date(); SimpleDateFormat format = new SimpleDateFormat(pattern); String expected = format.format(now); Value result = evaluate("format('" + pattern + "')", testType.valueOf(now)).getValue(); assertFormatResult(result, expected, false); result = evaluate("format(newValue('" + pattern + "'))", testType.valueOf(now)).getValue(); assertFormatResult(result, expected, false); // sequence result = evaluate("format('" + pattern + "')", testType.sequenceOf(ImmutableList.of(testType.valueOf(now)))) .getValue(); assertFormatResult(result, expected, true); } private void assertFormatResult(Value result, String expected, boolean sequence) { assertThat(result).isNotNull(); assertThat(result.isSequence()).isEqualTo(sequence); assertThat(result.getValueType()).isEqualTo(TextType.get()); if(sequence) { ValueSequence seq = result.asSequence(); assertThat(seq.getSize()).isEqualTo(1); assertThat(seq.get(0).getValue().toString()).isEqualTo(expected); } else { assertThat(expected).isEqualTo(result.toString()); } } }