Skip to content

Commit

Permalink
[Feature #21] Add validation for bad formats and more tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew-Kulich committed Feb 11, 2022
1 parent 96eadbe commit 7cd701d
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
import org.apache.jena.sparql.function.FunctionEnv;
import org.topbraid.spin.arq.AbstractFunction3;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.time.format.FormatStyle;
import java.util.*;

/**
* Converts a string in a semi-structured format into a xsd:date, xsd:dateTime or xsd:time literal.
Expand All @@ -29,15 +32,26 @@ public String getTypeURI() {
return TYPE_IRI;
}

/**
* @param text The input string.
* @param pattern The template of the input string.
* @param patternLanguage The code of the language (e.g. \"de\" for German) to use for parsing. May be <code>null</code>.
* @param env Environment of the function. May be <code>null</code>.
* @return NodeValue with parsed date/time/datetime.
*/
@Override
public NodeValue exec(Node text, Node pattern, Node patternLanguage, FunctionEnv env) {
String textValue, patternValue;
try{
textValue = text.getLiteralValue().toString();
patternValue = pattern.getLiteralValue().toString();
}catch(Exception e){
throw new IllegalArgumentException("Some of required parameters were not provided.");
}

String textValue = text.getLiteralValue().toString();
String patternValue = pattern.getLiteralValue().toString();
String patternLanguageValue = patternLanguage.getLiteralValue().toString();
Locale locale = new Locale(patternLanguageValue);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(patternValue).withLocale(locale);
Optional<Node> patternLanguageNode = Optional.ofNullable(patternLanguage);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(patternValue);
patternLanguageNode.ifPresent(node -> checkLocaleFormat(node, formatter, textValue));

try{
LocalDateTime localDateTime = LocalDateTime.parse(textValue,formatter);
Expand All @@ -51,12 +65,29 @@ public NodeValue exec(Node text, Node pattern, Node patternLanguage, FunctionEnv

try{
LocalTime localTime = LocalTime.parse(textValue,formatter);
return getTimeNode(String.valueOf(localTime));
return getTimeNode(localTime.format(DateTimeFormatter.ofPattern("kk:mm:ss")));
}catch(Exception e){
throw new ParseException();
}
}

private void checkLocaleFormat(Node patternLanguageNode, DateTimeFormatter formatter, String textValue){
String patternLanguageValue = patternLanguageNode.getLiteralValue().toString();
formatter = formatter.withLocale(new Locale(patternLanguageValue));

LocalDate ld = LocalDate.parse(textValue,formatter);
LocalDate localeDate = LocalDate.of(ld.getYear(),ld.getMonthValue(),ld.getDayOfMonth());
DateTimeFormatter localeFormat = DateTimeFormatter
.ofLocalizedDate(FormatStyle.SHORT)
.withLocale( new Locale(patternLanguageValue));

String localeString = localeDate.format(localeFormat);

if(!textValue.contains(localeString)){
throw new IllegalArgumentException("Pattern does not corresponds to the pattern language.");
}
}

private NodeValue getDateNode(String date){
return getNode(date, XSDDatatype.XSDdate);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public class ParseDateTest {
@Test
public void execReturnsDate_ItalianLocale() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("02.11.2021");
Node pattern = createLiteral("dd.MM.yyyy");
Node patternLanguage = createLiteral("de");
Node text = createLiteral("02/11/21");
Node pattern = createLiteral("dd/MM/yy");
Node patternLanguage = createLiteral("it");

NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);
NodeValue expectedDate = getDateNode("2021-11-02");
Expand All @@ -34,9 +34,9 @@ public void execReturnsDate_ItalianLocale() {
@Test
public void execReturnsDate_EnglishLocale() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("2010-09-21");
Node pattern = createLiteral("yyyy-MM-dd");
Node patternLanguage = createLiteral("de");
Node text = createLiteral("9/21/10");
Node pattern = createLiteral("M/dd/yy");
Node patternLanguage = createLiteral("en");

NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);
NodeValue expectedDate = getDateNode("2010-09-21");
Expand All @@ -48,72 +48,123 @@ public void execReturnsDate_FrenchLocale() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("19/12/2016");
Node pattern = createLiteral("dd/MM/yyyy");
Node patternLanguage = createLiteral("de");
Node patternLanguage = createLiteral("fr");

NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);
NodeValue expectedDate = getDateNode("2016-12-19");
assertEquals(expectedDate, returnedDate);
}

@Test
public void execReturnsTimeWithSeconds() {
public void execReturnsTime_WithSeconds() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("09:10:10");
Node pattern = createLiteral("k:m:s");
Node patternLanguage = createLiteral("de");
NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);
NodeValue returnedTime = parseDate.exec(text, pattern, null, null);

NodeValue expectedDate = getTimeNode("09:10:10");
assertEquals(expectedDate, returnedDate);
NodeValue expectedTime = getTimeNode("09:10:10");
assertEquals(expectedTime, returnedTime);
}

@Test
public void execReturnsTimeWithoutSeconds() {
public void execReturnsTime_WithoutSeconds() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("23:59");
Node pattern = createLiteral("k:m");
Node patternLanguage = createLiteral("de");
NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);

NodeValue expectedDate = getTimeNode("23:59");
assertEquals(expectedDate, returnedDate);
NodeValue returnedTime = parseDate.exec(text, pattern, null, null);
NodeValue expectedTime = getTimeNode("23:59:00");

assertEquals(expectedTime, returnedTime);
}

@Test
public void execReturnsDateTime() {
public void execReturnsTime_OnlyHours() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("2001.07.04 12:08:56");
Node pattern = createLiteral("yyyy.MM.dd HH:mm:ss");
Node patternLanguage = createLiteral("en");
NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);
Node text = createLiteral("15");
Node pattern = createLiteral("k");

NodeValue expectedDate = getDateTimeNode("2001-07-04T12:08:56");
assertEquals(expectedDate, returnedDate);
NodeValue returnedTime = parseDate.exec(text, pattern, null, null);
NodeValue expectedTime = getTimeNode("15:00:00");

assertEquals(expectedTime, returnedTime);
}


@Test
public void execReturnsDateTxime() {
public void execReturnsDateTime_FrenchLocale() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("2001.07.04 AD 12:08:56 PDT");
Node pattern = createLiteral("yyyy.MM.dd G HH:mm:ss z");
Node patternLanguage = createLiteral("dxxxe");
NodeValue returnedDate = parseDate.exec(text, pattern, patternLanguage, null);
Node text = createLiteral("19/12/2016 12:08:56");
Node pattern = createLiteral("dd/MM/yyyy HH:mm:ss");
Node patternLanguage = createLiteral("fr");

NodeValue expectedDate = getDateTimeNode("2001-07-04T12:08:56");
assertEquals(expectedDate, returnedDate);
NodeValue returnedDateTime = parseDate.exec(text, pattern, patternLanguage, null);
NodeValue expectedDateTime = getDateTimeNode("2016-12-19T12:08:56");

assertEquals(expectedDateTime, returnedDateTime);
}

@Test
public void execReturnsDateTime_complexPattern() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("2001.07.04 at 12:08:56 PDT");
Node pattern = createLiteral("yyyy.MM.dd 'at' HH:mm:ss z");

NodeValue returnedDateTime = parseDate.exec(text, pattern, null, null);
NodeValue expectedDateTime = getDateTimeNode("2001-07-04T12:08:56");

assertEquals(expectedDateTime, returnedDateTime);
}

@Test
public void execThrowsException_badInput() {
public void execReturnsDateTime_nullPatternLanguage() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("2001.07.04 12:08:56exception");
Node text = createLiteral("2022.01.01 23:59:59");
Node pattern = createLiteral("yyyy.MM.dd HH:mm:ss");
Node patternLanguage = createLiteral("de");

assertThrows(ParseException.class, () -> parseDate.exec(text, pattern, patternLanguage, null));
NodeValue returnedDateTime = parseDate.exec(text, pattern, null, null);
NodeValue expectedDateTime = getDateTimeNode("2022-01-01T23:59:59");

assertEquals(expectedDateTime, returnedDateTime);
}


@Test
public void execThrowsException_badInput() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("Lorem Ipsum");
Node pattern = createLiteral("yyyy.MM.dd");

assertThrows(ParseException.class, () -> parseDate.exec(text, pattern, null, null));
}

@Test
public void execThrowsException_nullInputText() {
ParseDate parseDate = new ParseDate();
Node pattern = createLiteral("yyyy.MM.dd");

assertThrows(IllegalArgumentException.class, () -> parseDate.exec(null, pattern, null, null));
}

@Test
public void execThrowsException_nullPattern() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("21/10/2013");

assertThrows(IllegalArgumentException.class, () -> parseDate.exec(text, null, null, null));
}

@Test
public void execThrowsException_badPatternLanguage() {
ParseDate parseDate = new ParseDate();
Node text = createLiteral("19/12/2016");
Node pattern = createLiteral("dd/MM/yyyy");
Node patternLanguage = createLiteral("en");

assertThrows(IllegalArgumentException.class, () -> parseDate.exec(text, pattern, patternLanguage, null));
}


private NodeValue getDateNode(String date){
return getNode(date, XSDDatatype.XSDdate);
}
Expand Down

0 comments on commit 7cd701d

Please sign in to comment.