Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TimeOfDayQuestionResult predicate comparison #1392

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 13 additions & 5 deletions ResearchKit/Common/ORKResultPredicate.m
Expand Up @@ -215,7 +215,15 @@ + (NSPredicate *)predicateMatchingResultSelector:(ORKResultSelector *)resultSele
// or part of an additional subquery predicate (for question results with an array of answers, like ORKChoiceQuestionResult).
for (NSString *subPredicateFormat in subPredicateFormatArray) {
if (!areSubPredicateFormatsSubquery) {
[format appendString:@" AND $z."];
if ([subPredicateFormat hasPrefix:@"("]) {
/*
For complex queries (e.g. TimeOfDay) where nested logic is needed, we will skip the $z. prefix
and allow the caller to handle. NOTE: caller will need to prefix any key references with '$z'
*/
[format appendString:@" AND "];
} else {
[format appendString:@" AND $z."];
}
[format appendString:subPredicateFormat];
} else {
[format appendString:@" AND SUBQUERY($z."];
Expand Down Expand Up @@ -399,14 +407,14 @@ + (NSPredicate *)predicateForTimeOfDayQuestionResultWithResultSelector:(ORKResul
maximumExpectedHour:(NSInteger)maximumExpectedHour
maximumExpectedMinute:(NSInteger)maximumExpectedMinute {
return [self predicateMatchingResultSelector:resultSelector
subPredicateFormatArray:@[ @"answer.hour >= %@",
@"answer.minute >= %@",
@"answer.hour <= %@",
@"answer.minute <= %@" ]
subPredicateFormatArray:@[ @"($z.answer.hour > %@ OR ($z.answer.hour == %@ AND $z.answer.minute >= %@)) AND ($z.answer.hour < %@ OR ($z.answer.hour == %@ AND $z.answer.minute <= %@))" ]
subPredicateFormatArgumentArray:@[ @(minimumExpectedHour),
@(minimumExpectedHour),
@(minimumExpectedMinute),
@(maximumExpectedHour),
@(maximumExpectedHour),
@(maximumExpectedMinute) ]];

}

+ (NSPredicate *)predicateForTimeIntervalQuestionResultWithResultSelector:(ORKResultSelector *)resultSelector
Expand Down
11 changes: 11 additions & 0 deletions ResearchKitTests/ORKTaskTests.m
Expand Up @@ -1297,6 +1297,17 @@ - (void)testResultPredicatesWithTaskIdentifier:(NSString *)taskIdentifier
maximumExpectedHour:expectedDateComponentsMaximum.hour
maximumExpectedMinute:expectedDateComponentsMaximum.minute] evaluateWithObject:taskResults substitutionVariables:substitutionVariables]);

expectedDateComponentsMinimum.hour = 6;
expectedDateComponentsMinimum.minute = 0;
expectedDateComponentsMaximum.hour = 7;
expectedDateComponentsMaximum.minute = 0;
XCTAssertTrue([[ORKResultPredicate predicateForTimeOfDayQuestionResultWithResultSelector:resultSelector
minimumExpectedHour:expectedDateComponentsMinimum.hour
minimumExpectedMinute:expectedDateComponentsMinimum.minute
maximumExpectedHour:expectedDateComponentsMaximum.hour
maximumExpectedMinute:expectedDateComponentsMaximum.minute] evaluateWithObject:taskResults substitutionVariables:substitutionVariables]);


// ORKTimeIntervalQuestionResult
resultSelector.resultIdentifier = FloatNumericStepIdentifier;
XCTAssertTrue([[ORKResultPredicate predicateForTimeIntervalQuestionResultWithResultSelector:resultSelector
Expand Down
2 changes: 1 addition & 1 deletion ResearchKitTests/ORKTestResultPredicateType.swift
Expand Up @@ -44,7 +44,7 @@ enum TestPredicateFormat: String {
case timeMax = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND $z.answer <= 100).@count > 0).@count > 0).@count > 0"
case timeMin = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND $z.answer >= 16).@count > 0).@count > 0).@count > 0"
case timeMinAndMax = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND $z.answer >= 10 AND $z.answer <= 1000).@count > 0).@count > 0).@count > 0"
case timeOfDay = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND $z.answer.hour >= 2 AND $z.answer.minute >= 30 AND $z.answer.hour <= 10 AND $z.answer.minute <= 10).@count > 0).@count > 0).@count > 0"
case timeOfDay = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND ($z.answer.hour > 2 OR ($z.answer.hour == 2 AND $z.answer.minute >= 30)) AND ($z.answer.hour < 10 OR ($z.answer.hour == 10 AND $z.answer.minute <= 10))).@count > 0).@count > 0).@count > 0"
case boolean = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND $z.answer == 1).@count > 0).@count > 0).@count > 0"
case nilPredicate = "SUBQUERY(SELF, $x, $x.identifier == $ORK_TASK_IDENTIFIER AND SUBQUERY($x.results, $y, $y.identifier == %@ AND $y.isPreviousResult == 0 AND SUBQUERY($y.results, $z, $z.identifier == %@ AND $z.answer == nil).@count > 0).@count > 0).@count > 0"
}