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

Implement inequality operators (<, >, <=, >=) in the enable when statement #848

Merged
merged 20 commits into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Review changes.
  • Loading branch information
santosh-pingle committed Nov 18, 2021
commit 90f4327d293cecbf1cbd4beae3c32eb1182d3c6a
13 changes: 13 additions & 0 deletions common/src/main/java/com/google/android/fhir/MoreTypes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.google.android.fhir
import java.util.Calendar
import java.util.Date
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.Quantity
import org.hl7.fhir.r4.model.Type

/**
Expand Down Expand Up @@ -62,6 +63,18 @@ operator fun Type.compareTo(value: Type?): Int {
this.fhirType().equals("dateTime") -> {
return this.dateTimeValue().value.compareTo(value.dateTimeValue().value)
}
this.fhirType().equals("Quantity") -> {
santosh-pingle marked this conversation as resolved.
Show resolved Hide resolved
val quantity =
UnitConverter.getCanonicalForm(UcumValue((this as Quantity).code, this.value))
val anotherQuantity =
UnitConverter.getCanonicalForm(UcumValue((value as Quantity).code, value.value))
if (quantity.code != anotherQuantity.code) {
throw IllegalArgumentException(
"Cannot compare different quantity codes: ${quantity.code} and ${anotherQuantity.code}"
)
}
return quantity.value.compareTo(anotherQuantity.value)
}
else -> {
throw NotImplementedError()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.android.fhir.datacapture.enablement

import com.google.android.fhir.compareTo
import com.google.android.fhir.equals
import java.lang.IllegalStateException
import org.hl7.fhir.r4.model.Questionnaire
Expand Down Expand Up @@ -127,6 +128,26 @@ private val Questionnaire.QuestionnaireItemEnableWhenComponent.predicate:
Questionnaire.QuestionnaireItemOperator.NOT_EQUAL -> {
!equals(it.value, answer)
}
Questionnaire.QuestionnaireItemOperator.GREATER_THAN -> {
// True if whether at least no answer has a value that is greater than the enableWhen
// answer.
answer >= it.value
}
Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL -> {
// True if whether at least no answer has a value that is greater or equal to the
// enableWhen answer.
answer > it.value
}
Questionnaire.QuestionnaireItemOperator.LESS_THAN -> {
// True if whether at least no answer has a value that is less than the enableWhen
// answer.
answer <= it.value
}
Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL -> {
// True if whether at least no answer has a value that is less or equal to the
// enableWhen answer.
answer < it.value
}
else -> throw NotImplementedError("Enable when operator $operator is not implemented.")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ package com.google.android.fhir.datacapture.enablement
import android.os.Build
import com.google.common.truth.BooleanSubject
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertFailsWith
import org.hl7.fhir.r4.model.BooleanType
import org.hl7.fhir.r4.model.Coding
import org.hl7.fhir.r4.model.IntegerType
import org.hl7.fhir.r4.model.Quantity
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import org.hl7.fhir.r4.model.Type
Expand Down Expand Up @@ -383,6 +385,137 @@ class EnablementEvaluatorTest {
.isFalse()
}

@Test
santosh-pingle marked this conversation as resolved.
Show resolved Hide resolved
fun evaluate_greaterThan_noAnswersGreaterThanEnableWhenAnswer_shouldReturnTrue() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN,
expected = IntegerType(10),
actual = listOf(IntegerType(5))
)
)
.isTrue()
}

@Test
fun evaluate_greaterThan_answersGreaterThanEnableWhenAnswer_shouldReturnFalse() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN,
expected = IntegerType(10),
actual = listOf(IntegerType(20))
)
)
.isFalse()
}

@Test
fun evaluate_greaterOrEqual_noAnswersGreaterOrEqualEnableWhenAnswer_shouldReturnTrue() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL,
expected = IntegerType(10),
actual = listOf(IntegerType(5))
)
)
.isTrue()
}

@Test
fun evaluate_greaterOrEqual_answersGreaterOrEqualEnableWhenAnswer_shouldReturnFalse() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL,
expected = IntegerType(10),
actual = listOf(IntegerType(10))
)
)
.isFalse()
}

@Test
fun evaluate_lessThan_noAnswersLessThanEnableWhenAnswer_shouldReturnTrue() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN,
expected = IntegerType(10),
actual = listOf(IntegerType(20))
)
)
.isTrue()
}

@Test
fun evaluate_lessThan_answersLessThanEnableWhenAnswer_shouldReturnFalse() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN,
expected = IntegerType(10),
actual = listOf(IntegerType(5))
)
)
.isFalse()
}

@Test
fun evaluate_lessOrEqual_noAnswerLessOrEqualEnableWhenAnswer_shouldReturnTrue() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL,
expected = IntegerType(10),
actual = listOf(IntegerType(20))
)
)
.isTrue()
}

@Test
fun evaluate_lessOrEqual_answerLessOrEqualEnableWhenAnswer_shouldReturnFalse() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL,
expected = IntegerType(10),
actual = listOf(IntegerType(10))
)
)
.isFalse()
}

@Test
fun evaluate_quantityType_lessOrEqual_noAnswerLessOrEqualEnableWhenAnswer_shouldReturnTrue() {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL,
expected = Quantity().setCode("h").setValue(10),
actual = listOf(Quantity().setCode("h").setValue(20))
)
)
.isTrue()
}

@Test
fun evaluate_quantityWithDifferentCodes_shouldFail() {
assertFailsWith<IllegalArgumentException> {
evaluateEnableWhen(
behavior = null,
EnableWhen(
operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL,
expected = Quantity().setCode("h").setValue(10),
actual = listOf(Quantity().setCode("kg").setValue(5))
)
)
}
}

/**
* Evaluates multiple `enableWhen` constraints according to the `behavior` (any or all).
*
Expand Down