TimeColumnTest.java
/*
* Licensed 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 tech.tablesaw.api;
import static org.junit.jupiter.api.Assertions.*;
import static tech.tablesaw.columns.times.PackedLocalTime.getMinuteOfDay;
import static tech.tablesaw.columns.times.PackedLocalTime.getSecondOfDay;
import static tech.tablesaw.columns.times.PackedLocalTime.of;
import java.nio.ByteBuffer;
import java.sql.Time;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import tech.tablesaw.columns.Column;
import tech.tablesaw.columns.times.TimeColumnType;
import tech.tablesaw.columns.times.TimeParser;
import tech.tablesaw.selection.Selection;
public class TimeColumnTest {
private TimeColumn column1;
@BeforeEach
public void setUp() {
Table table = Table.create("Test");
column1 = TimeColumn.create("Game time");
table.addColumns(column1);
}
@Test
public void testMaxAndMin() {
column1.appendCell("05:15:30");
column1.appendCell("10:15:30");
column1.appendCell("07:04:02");
assertEquals(LocalTime.of(5, 15, 30), column1.min());
assertEquals(LocalTime.of(10, 15, 30), column1.max());
}
@Test
public void testContains() {
column1.appendCell("05:15:30");
column1.appendCell("10:15:30");
column1.appendCell("07:04:02");
assertTrue(column1.contains(LocalTime.of(5, 15, 30)));
assertTrue(column1.contains(LocalTime.of(10, 15, 30)));
assertFalse(column1.contains(LocalTime.of(9, 15, 30)));
}
@Test
public void testTopAndBottom() {
fillLargerColumn();
List<LocalTime> top = column1.top(3);
List<LocalTime> bottom = column1.bottom(3);
assertTrue(bottom.contains(LocalTime.of(0, 4, 2)));
assertTrue(bottom.contains(LocalTime.of(3, 6, 2)));
assertTrue(bottom.contains(LocalTime.of(4, 4, 2)));
assertEquals(3, bottom.size());
assertTrue(top.contains(LocalTime.of(18, 4, 2)));
assertTrue(top.contains(LocalTime.of(14, 4, 2)));
assertTrue(top.contains(LocalTime.of(15, 4, 2)));
assertEquals(3, top.size());
}
@Test
public void testSorting() {
fillLargerColumn();
List<LocalTime> top = column1.top(3);
column1.sortAscending();
Column<?> first = column1.first(3);
TimeColumn timeColumn = (TimeColumn) first;
List<LocalTime> sortedA = timeColumn.asList();
column1.sortDescending();
List<LocalTime> sortedD = column1.first(3).asList();
assertNull(sortedA.get(0));
assertEquals(LocalTime.of(0, 4, 2), sortedA.get(1));
assertEquals(LocalTime.of(3, 6, 2), sortedA.get(2));
assertEquals(top, sortedD);
}
@Test
public void testAppendColumn() {
column1.appendInternal(of(5, 15, 30));
column1.appendInternal(of(10, 15, 30));
column1.appendInternal(of(7, 4, 2));
column1.appendInternal(of(4, 4, 2));
column1.appendInternal(of(18, 4, 2));
TimeColumn column2 = TimeColumn.create("TC2");
column2.appendInternal(of(15, 4, 2));
column2.appendInternal(of(14, 4, 2));
column2.appendInternal(of(0, 4, 2));
column2.appendInternal(of(3, 6, 2));
column2.appendInternal(of(11, 4, 2));
column1.append(column2);
assertEquals(10, column1.size());
assertTrue(column1.contains(LocalTime.of(14, 4, 2)));
}
@Test
public void testAppendCell() {
column1.appendCell("10:15:30");
column1.appendCell("11:30:00");
column1.appendCell("14:00:00");
column1.appendCell("18:15:30");
assertEquals(4, column1.size());
}
@Test
public void testCustomParser() {
// Just do enough to ensure the parser is wired up correctly
TimeParser customParser = new TimeParser(ColumnType.LOCAL_TIME);
customParser.setMissingValueStrings(Arrays.asList("not here"));
column1.setParser(customParser);
column1.appendCell("not here");
assertTrue(column1.isMissing(column1.size() - 1));
column1.appendCell("10:15:30");
assertFalse(column1.isMissing(column1.size() - 1));
}
@Test
public void testSet() {
column1.appendCell("10:15:30");
column1.appendCell("11:30:00");
column1.appendCell("14:00:00");
column1.appendCell("18:15:30");
column1.set(column1.isBeforeNoon(), LocalTime.NOON);
assertEquals(LocalTime.NOON, column1.get(0));
assertEquals(LocalTime.NOON, column1.get(1));
assertNotEquals(LocalTime.NOON, column1.get(2));
assertNotEquals(LocalTime.NOON, column1.get(3));
}
@Test
public void testAppendCell2() {
column1.appendCell("12:18:03 AM");
column1.appendCell("8:18:03 AM");
column1.appendCell("12:18:03 AM");
assertEquals(3, column1.size());
}
@Test
public void copy() {
fillLargerColumn();
TimeColumn column2 = column1.copy();
for (int i = 0; i < column1.size(); i++) {
assertEquals(column2.getIntInternal(i), column1.getIntInternal(i));
}
assertEquals(column1.name(), column2.name());
}
@Test
public void clear() {
fillLargerColumn();
assertEquals(11, column1.size());
column1.clear();
assertEquals(0, column1.size());
}
@Test
public void summary() {
fillLargerColumn();
Table t = column1.summary();
assertEquals("11", t.getString(0, "Value"));
assertEquals("1", t.getString(1, "Value"));
assertEquals("00:04:02", t.getString(2, "Value"));
assertEquals("18:04:02", t.getString(3, "Value"));
}
@Test
public void asBytesAndByteSize() {
fillLargerColumn();
assertEquals(4, column1.byteSize());
assertEquals(column1.getPackedTime(0), ByteBuffer.wrap(column1.asBytes(0)).getInt());
}
@Test
public void countMissing() {
fillLargerColumn();
column1.appendInternal(TimeColumnType.missingValueIndicator());
column1.appendInternal(TimeColumnType.missingValueIndicator());
assertEquals(3, column1.countMissing());
}
@Test
public void isMissingIsNotMissing() {
fillLargerColumn();
column1.appendInternal(TimeColumnType.missingValueIndicator());
column1.appendInternal(TimeColumnType.missingValueIndicator());
Selection s = column1.isMissing();
assertEquals(3, s.size());
Selection s2 = column1.isNotMissing();
assertEquals(10, s2.size());
}
@Test
public void countUnique() {
fillLargerColumn();
column1.appendInternal(TimeColumnType.missingValueIndicator());
assertEquals(11, column1.countUnique());
}
@Test
public void basicCountUnique() {
TimeColumn column1 = TimeColumn.create("time");
column1.append(LocalTime.of(18, 4, 4));
column1.append(LocalTime.of(18, 4, 4));
column1.append(LocalTime.of(20, 4, 4));
column1.appendMissing();
assertEquals(3, column1.countUnique());
assertEquals(3, column1.unique().size());
}
@Test
public void lag() {
fillLargerColumn();
TimeColumn column2 = column1.lag(2);
Table t = Table.create("t");
t.addColumns(column1, column2);
for (int i = 0; i < column1.size() - 2; i++) {
assertEquals(column2.getIntInternal(i + 2), column1.getIntInternal(i));
}
}
@Test
public void lead() {
fillLargerColumn();
TimeColumn column2 = column1.lead(2);
Table t = Table.create("t");
t.addColumns(column1, column2);
for (int i = 0; i < column1.size() - 2; i++) {
assertEquals(column2.getIntInternal(i), column1.getIntInternal(i + 2));
}
}
@Test
public void minuteOfDay() {
fillLargerColumn();
IntColumn column2 = column1.minuteOfDay();
for (int i = 0; i < column1.size() - 2; i++) {
assertEquals(column2.getInt(i), getMinuteOfDay(column1.getPackedTime(i)), 0.0001);
}
}
@Test
public void secondOfDay() {
fillLargerColumn();
IntColumn column2 = column1.secondOfDay();
for (int i = 0; i < column1.size() - 2; i++) {
assertEquals(column2.getInt(i), getSecondOfDay(column1.getPackedTime(i)), 0.0001);
}
}
@Test
public void testPlusHours() {
fillColumn();
TimeColumn column2 = column1.plusHours(3);
IntColumn numberColumn = column2.differenceInHours(column1);
int expected = -3;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testTruncatedTo() {
fillColumn();
TimeColumn column2 = column1.truncatedTo(ChronoUnit.HOURS);
assertEquals(column1.get(0).getHour(), column2.get(0).getHour());
assertEquals(0, column2.get(0).getMinute());
assertEquals(0, column2.get(0).getSecond());
assertEquals(0, column2.get(0).getNano());
assertEquals(TimeColumnType.missingValueIndicator(), column2.getIntInternal(2));
}
@Test
public void testWithHour() {
fillColumn();
TimeColumn column2 = column1.withHour(3);
assertEquals(3, column2.hour().min(), 0.001);
assertEquals(3, column2.hour().max(), 0.001);
}
@Test
public void testWithMinute() {
fillColumn();
TimeColumn column2 = column1.withMinute(3);
assertEquals(3, column2.minute().min(), 0.001);
assertEquals(3, column2.minute().max(), 0.001);
}
@Test
public void testWithSecond() {
fillColumn();
TimeColumn column2 = column1.withSecond(3);
assertEquals(3, column2.second().min(), 0.001);
assertEquals(3, column2.second().max(), 0.001);
}
@Test
public void testSecond() {
fillColumn();
IntColumn second = column1.second();
assertEquals(2, second.get(0), 0.001);
assertEquals(30, second.get(1), 0.001);
assertNull(second.get(2));
}
@Test
public void testMinute() {
fillColumn();
IntColumn minute = column1.minute();
assertEquals(4, minute.get(0), 0.001);
assertEquals(15, minute.get(1), 0.001);
assertNull(minute.get(2));
}
@Test
public void testWithMillisecond() {
fillColumn();
TimeColumn column2 = column1.withMillisecond(3);
assertEquals(3, column2.milliseconds().min(), 0.001);
assertEquals(3, column2.milliseconds().max(), 0.001);
}
@Test
public void testMinusHours() {
fillColumn();
TimeColumn column2 = column1.minusHours(0);
IntColumn numberColumn = column2.differenceInHours(column1);
int expected = 0;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testPlusMinutes() {
fillColumn();
TimeColumn column2 = column1.plusMinutes(30);
IntColumn numberColumn = column2.differenceInMinutes(column1);
int expected = -30;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testMinusMinutes() {
fillColumn();
TimeColumn column2 = column1.minusMinutes(30);
IntColumn numberColumn = column2.differenceInMinutes(column1);
int expected = 30;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testPlusSeconds() {
fillColumn();
TimeColumn column2 = column1.plusSeconds(101);
IntColumn numberColumn = column2.differenceInSeconds(column1);
int expected = -101;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testMinusSeconds() {
fillColumn();
TimeColumn column2 = column1.minusSeconds(101);
IntColumn numberColumn = column2.differenceInSeconds(column1);
int expected = 101;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testPlusMilliseconds() {
fillColumn();
TimeColumn column2 = column1.plusMilliseconds(101);
IntColumn numberColumn = column2.differenceInMilliseconds(column1);
int expected = -101;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testMinusMilliseconds() {
fillColumn();
TimeColumn column2 = column1.minusMilliseconds(101);
IntColumn numberColumn = column2.differenceInMilliseconds(column1);
int expected = 101;
assertMinAndMaxEquals(expected, numberColumn);
}
@Test
public void testNull() {
TimeColumn col = TimeColumn.create("Game time");
col.appendCell(null);
assertNull(col.get(0));
}
@Test
public void testAppendObjNull() {
TimeColumn returned = column1.appendObj(null);
assertEquals(column1, returned);
assertEquals(1, returned.size());
assertTrue(returned.isMissing(0));
}
@Test
public void testAppendObjLocalTime() {
LocalTime localTime = LocalTime.of(9, 10, 42);
TimeColumn returned = column1.appendObj(localTime);
assertEquals(column1, returned);
assertEquals(1, returned.size());
assertEquals(LocalTime.of(9, 10, 42), returned.get(0));
}
@Test
public void testAppendObjTime() {
Time time = Time.valueOf("09:10:42");
TimeColumn returned = column1.appendObj(time);
assertEquals(column1, returned);
assertEquals(1, returned.size());
assertEquals(LocalTime.of(9, 10, 42), returned.get(0));
}
@Test
public void testAppendObjIllegal() {
assertThrows(IllegalArgumentException.class, () -> column1.appendObj(new Object()));
}
private void assertMinAndMaxEquals(int expected, IntColumn numberColumn) {
assertEquals(expected, (int) numberColumn.min());
assertEquals(expected, (int) numberColumn.max());
}
private void fillColumn() {
column1.appendCell("07:04:02");
column1.appendCell("10:15:30");
column1.appendCell("");
}
private void fillLargerColumn() {
column1.appendInternal(of(5, 15, 30));
column1.appendInternal(of(10, 15, 30));
column1.appendInternal(of(7, 4, 2));
column1.appendInternal(of(4, 4, 2));
column1.appendCell("");
column1.appendInternal(of(18, 4, 2));
column1.appendInternal(of(15, 4, 2));
column1.appendInternal(of(14, 4, 2));
column1.appendInternal(of(0, 4, 2));
column1.appendInternal(of(3, 6, 2));
column1.appendInternal(of(11, 4, 2));
}
}