Date comparisons through REQ-WA103-QO24, fractional seconds comparisons
This commit is contained in:
parent
d412f0bdd4
commit
521920a1f8
Binary file not shown.
|
@ -138,7 +138,7 @@
|
|||
<Parameter Name="ToUpperValue" Value="MAIN" />
|
||||
|
||||
<!-- REQUIRED: Date Fields for testing -->
|
||||
<Parameter Name="DateField" Value="ModificationTimestamp" />
|
||||
<Parameter Name="DateField" Value="ListingContractDate" />
|
||||
<Parameter Name="DateTimeValue" Value="2018-12-31T23:55:55-09:00" />
|
||||
<Parameter Name="DateValue" Value="2018-12-31" />
|
||||
<Parameter Name="YearValue" Value="2018" />
|
||||
|
@ -496,57 +496,57 @@
|
|||
|
||||
<Request
|
||||
TestDescription="Query Support: $filter: Date: year"
|
||||
RequirementId="REQ-WA103-QO18"
|
||||
RequirementId="REQ-WA103-QO18.1"
|
||||
MetallicLevel="Gold"
|
||||
Capability="Filterability ($filter)"
|
||||
WebAPIReference="2.4.4"
|
||||
OutputFile="REQ-WA103-QO18_DateYear.json"
|
||||
OutputFile="REQ-WA103-QO18.1.json"
|
||||
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&$select=*Parameter_SelectList*&$filter=*Parameter_DateField* ne null and year(*Parameter_DateField*) eq *Parameter_YearValue**Parameter_RequiredParameters*"
|
||||
/>
|
||||
|
||||
<Request
|
||||
TestDescription="Query Support: $filter: Time: year"
|
||||
RequirementId="REQ-WA103-QO18"
|
||||
RequirementId="REQ-WA103-QO18.2"
|
||||
MetallicLevel="Gold"
|
||||
Capability="Filterability ($filter)"
|
||||
WebAPIReference="2.4.4"
|
||||
OutputFile="REQ-WA103-QO18_TimeYear.json"
|
||||
OutputFile="REQ-WA103-QO18.2.json"
|
||||
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&$select=*Parameter_SelectList*&$filter=*Parameter_TimestampField* ne null and year(*Parameter_TimestampField*) eq *Parameter_YearValue**Parameter_RequiredParameters*"
|
||||
/>
|
||||
|
||||
<Request
|
||||
TestDescription="Query Support: $filter: Date: month"
|
||||
RequirementId="REQ-WA103-QO19"
|
||||
RequirementId="REQ-WA103-QO19.1"
|
||||
MetallicLevel="Gold"
|
||||
Capability="Filterability ($filter)"
|
||||
WebAPIReference="2.4.4"
|
||||
OutputFile="REQ-WA103-QO19_DateMonth.json"
|
||||
OutputFile="REQ-WA103-QO19.1.json"
|
||||
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&$select=*Parameter_SelectList*&$filter=*Parameter_DateField* ne null and month(*Parameter_DateField*) eq *Parameter_MonthValue**Parameter_RequiredParameters*"
|
||||
/>
|
||||
|
||||
<Request
|
||||
TestDescription="Query Support: $filter: Time: month"
|
||||
RequirementId="REQ-WA103-QO19"
|
||||
RequirementId="REQ-WA103-QO19.2"
|
||||
MetallicLevel="Gold"
|
||||
Capability="Filterability ($filter)"
|
||||
WebAPIReference="2.4.4"
|
||||
OutputFile="REQ-WA103-QO19_TimeMonth.json"
|
||||
OutputFile="REQ-WA103-QO19.2.json"
|
||||
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&$select=*Parameter_SelectList*&$filter=*Parameter_TimestampField* ne null and month(*Parameter_TimestampField*) eq *Parameter_MonthValue**Parameter_RequiredParameters*"
|
||||
/>
|
||||
|
||||
<Request
|
||||
TestDescription="Query Support: $filter: Date: day"
|
||||
RequirementId="REQ-WA103-QO20"
|
||||
RequirementId="REQ-WA103-QO20.1"
|
||||
MetallicLevel="Gold"
|
||||
Capability="Filterability ($filter)"
|
||||
WebAPIReference="2.4.4"
|
||||
OutputFile="REQ-WA103-QO20_DateDay.json"
|
||||
OutputFile="REQ-WA103-QO20.1.json"
|
||||
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_TopCount*&$select=*Parameter_SelectList*&$filter=*Parameter_DateField* ne null and day(*Parameter_DateField*) eq *Parameter_DayValue**Parameter_RequiredParameters*"
|
||||
/>
|
||||
|
||||
<Request
|
||||
TestDescription="Query Support: $filter: Time: day"
|
||||
RequirementId="REQ-WA103-QO20"
|
||||
RequirementId="REQ-WA103-QO20.2"
|
||||
MetallicLevel="Gold"
|
||||
Capability="Filterability ($filter)"
|
||||
WebAPIReference="2.4.4"
|
||||
|
|
|
@ -245,3 +245,83 @@ Feature: Web API Server 1.0.2 Certification
|
|||
And the response is valid JSON
|
||||
And the response has results
|
||||
And DateTimeOffset data in "Parameter_TimestampField" is sorted in "desc" order
|
||||
|
||||
@REQ-WA103-QO18.1 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: year
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO18.1"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "year" data in Date Field "Parameter_DateField" "eq" "Parameter_YearValue"
|
||||
|
||||
@REQ-WA103-QO18.2 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: year comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO18.2"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "year" data in Timestamp Field "Parameter_TimestampField" "eq" "Parameter_YearValue"
|
||||
|
||||
@REQ-WA103-QO19.1 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: month
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO19.1"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "month" data in Date Field "Parameter_DateField" "eq" "Parameter_MonthValue"
|
||||
|
||||
@REQ-WA103-QO19.2 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: month comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO19.2"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "month" data in Timestamp Field "Parameter_TimestampField" "eq" "Parameter_MonthValue"
|
||||
|
||||
@REQ-WA103-QO20.1 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: day
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO20.1"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "day" data in Date Field "Parameter_DateField" "eq" "Parameter_DayValue"
|
||||
|
||||
@REQ-WA103-QO20.2 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: day comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO20.2"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "day" data in Timestamp Field "Parameter_TimestampField" "eq" "Parameter_DayValue"
|
||||
|
||||
@REQ-WA103-QO21 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: hour comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO21"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "hour" data in Timestamp Field "Parameter_TimestampField" "eq" "Parameter_HourValue"
|
||||
|
||||
@REQ-WA103-QO22 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: minute comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO22"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "minute" data in Timestamp Field "Parameter_TimestampField" "gt" "Parameter_MinuteValue"
|
||||
|
||||
@REQ-WA103-QO23 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: second comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO23"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "second" data in Timestamp Field "Parameter_TimestampField" "lt" "Parameter_SecondValue"
|
||||
|
||||
@REQ-WA103-QO24 @gold @2.4.4 @filterability-endorsement
|
||||
Scenario: Query Support: $filter: Date: fractional seconds comparison with timestamp
|
||||
When a GET request is made to the resolved Url in "REQ-WA103-QO24"
|
||||
Then the server responds with a status code of 200
|
||||
And the response is valid JSON
|
||||
And the response has results
|
||||
And "fractional" data in Timestamp Field "Parameter_TimestampField" "lt" "Parameter_FractionalValue"
|
|
@ -28,7 +28,7 @@ import java.io.*;
|
|||
import java.net.URI;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -500,6 +500,11 @@ public class WebAPIServer_1_0_2 implements En {
|
|||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Year comparison glue
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Timestamp comparison glue
|
||||
*/
|
||||
|
@ -592,6 +597,60 @@ public class WebAPIServer_1_0_2 implements En {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
And("^\"([^\"]*)\" data in Date Field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String stringDatePart, String parameterFieldName, String op, String parameterAssertedValue) -> {
|
||||
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
|
||||
AtomicReference<Integer> fieldValue = new AtomicReference<>();
|
||||
AtomicInteger assertedValue = new AtomicInteger();
|
||||
AtomicReference<String> datePart = new AtomicReference<>(stringDatePart.toLowerCase());
|
||||
|
||||
try {
|
||||
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, settings)));
|
||||
LOG.info("Asserted value is: " + assertedValue.get());
|
||||
|
||||
from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
||||
try {
|
||||
fieldValue.set(Utils.getDatePart(datePart.get(), item.get(fieldName)));
|
||||
assertTrue(Utils.compare(fieldValue.get(), op, assertedValue.get()));
|
||||
} catch (Exception ex){
|
||||
//fail();
|
||||
LOG.error("ERROR: exception thrown." + ex);
|
||||
}
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
fail();
|
||||
LOG.error("ERROR: exception thrown." + ex);
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
* Year comparison from Timestamp Field
|
||||
* TODO: consolidate with Year comparison with Date Field
|
||||
*/
|
||||
And("^\"([^\"]*)\" data in Timestamp Field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String stringDatePart, String parameterFieldName, String op, String parameterAssertedValue) -> {
|
||||
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
|
||||
AtomicReference<Integer> fieldValue = new AtomicReference<>();
|
||||
AtomicReference<Integer> assertedValue = new AtomicReference<>();
|
||||
AtomicReference<String> datePart = new AtomicReference<>(stringDatePart.toLowerCase());
|
||||
|
||||
try {
|
||||
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, settings)));
|
||||
LOG.info("Asserted value is: " + assertedValue.get().toString());
|
||||
|
||||
from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
||||
try {
|
||||
fieldValue.set(Utils.getTimestampPart(datePart.get(), item.get(fieldName).toString()));
|
||||
assertTrue(Utils.compare(fieldValue.get(), op, assertedValue.get()));
|
||||
} catch (Exception ex){
|
||||
fail();
|
||||
LOG.error("ERROR: exception thrown." + ex);
|
||||
}
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
fail();
|
||||
LOG.error("ERROR: exception thrown." + ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -609,6 +668,17 @@ public class WebAPIServer_1_0_2 implements En {
|
|||
LESS_THAN_OR_EQUAL = "le";
|
||||
}
|
||||
|
||||
private static class DateParts {
|
||||
private static final String
|
||||
YEAR = "year",
|
||||
MONTH = "month",
|
||||
DAY = "day",
|
||||
HOUR = "hour",
|
||||
MINUTE = "minute",
|
||||
SECOND = "second",
|
||||
FRACTIONAL = "fractional";
|
||||
}
|
||||
|
||||
private static class Utils {
|
||||
|
||||
/**
|
||||
|
@ -708,6 +778,34 @@ public class WebAPIServer_1_0_2 implements En {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Year Comparator
|
||||
* @param lhs Year to compare
|
||||
* @param op an OData binary operator to use for comparisons
|
||||
* @param rhs Timestamp to compare
|
||||
* @return true if lhs op rhs, false otherwise
|
||||
*/
|
||||
private static boolean compare(Year lhs, String op, Year rhs) {
|
||||
String operator = op.toLowerCase();
|
||||
boolean result = false;
|
||||
|
||||
if (operator.contentEquals(Operators.GREATER_THAN)) {
|
||||
result = lhs.isAfter(rhs);
|
||||
} else if (operator.contentEquals(Operators.GREATER_THAN_OR_EQUAL)) {
|
||||
result = lhs.isAfter(rhs) || lhs.equals(rhs);
|
||||
} else if (operator.contentEquals(Operators.EQ)) {
|
||||
result = lhs.equals(rhs);
|
||||
} else if (operator.contentEquals(Operators.NE)) {
|
||||
result = !lhs.equals(rhs);
|
||||
} else if (operator.contentEquals(Operators.LESS_THAN)) {
|
||||
result = lhs.isBefore(rhs);
|
||||
} else if (operator.contentEquals(Operators.LESS_THAN_OR_EQUAL)) {
|
||||
result = lhs.isBefore(rhs) || lhs.equals(rhs);
|
||||
}
|
||||
LOG.info("Compare: " + lhs + " " + operator + " " + rhs + " ==> " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Comparator
|
||||
* @param lhs Time to compare
|
||||
|
@ -860,6 +958,57 @@ public class WebAPIServer_1_0_2 implements En {
|
|||
return EdmDateTimeOffset.getInstance().valueOfString(edmDateTimeOffsetString, true, null, null, null, null, Date.class);
|
||||
}
|
||||
|
||||
/***
|
||||
* Tries to parse datePart from the given Object value
|
||||
* @param datePart the timestamp part, "Year", "Month", "Day", etc. to try and parse
|
||||
* @param value the value to try and parse
|
||||
* @return the Integer portion of the date if successful, otherwise throws an Exception
|
||||
* @exception throws an exception if value cannot be parsed into a date.
|
||||
*/
|
||||
private static Integer getDatePart(String datePart, Object value) throws EdmPrimitiveTypeException {
|
||||
LocalDate date = LocalDate.parse(parseDateFromEdmDateString(value.toString()).toString());
|
||||
switch (datePart) {
|
||||
case DateParts.YEAR:
|
||||
return date.getYear();
|
||||
case DateParts.MONTH:
|
||||
return date.getMonthValue();
|
||||
case DateParts.DAY:
|
||||
return date.getDayOfMonth();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Tries to parse datePart from the given Object value
|
||||
* @param timestampPart the timestamp part, "Year", "Month", "Day", etc. to try and parse
|
||||
* @param value the value to try and parse
|
||||
* @return the Integer portion of the date if successful, otherwise throws an Exception
|
||||
*/
|
||||
private static Integer getTimestampPart(String timestampPart, Object value) throws EdmPrimitiveTypeException {
|
||||
//Turns nanoseconds into two most significant 2 digits for fractional comparisons
|
||||
Integer ADJUSTMENT_FACTOR = 10000000;
|
||||
OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.toString());
|
||||
|
||||
if (timestampPart.equals(DateParts.YEAR)) {
|
||||
return offsetDateTime.getYear();
|
||||
} else if (timestampPart.equals(DateParts.MONTH)) {
|
||||
return offsetDateTime.getMonthValue();
|
||||
} else if (timestampPart.equals(DateParts.DAY)) {
|
||||
return offsetDateTime.getDayOfMonth();
|
||||
} else if (timestampPart.equals(DateParts.HOUR)) {
|
||||
return offsetDateTime.getHour();
|
||||
} else if (timestampPart.equals(DateParts.MINUTE)) {
|
||||
return offsetDateTime.getMinute();
|
||||
} else if (timestampPart.equals(DateParts.SECOND)) {
|
||||
return offsetDateTime.getSecond();
|
||||
} else if (timestampPart.equals(DateParts.FRACTIONAL)) {
|
||||
return offsetDateTime.getNano() / ADJUSTMENT_FACTOR;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given inputStream to a string.
|
||||
* @param inputStream the input stream to convert.
|
||||
|
|
Loading…
Reference in New Issue