From eb0d5df4e02f3e1cc4cc03e2297bf053157a028f Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 21 Oct 2021 16:09:17 +0530 Subject: [PATCH 01/15] Create common module --- common/.gitignore | 1 + common/build.gradle.kts | 14 ++++++++++++++ .../java/com/google/android/fhir/UnitConverter.kt | 8 ++++---- datacapture/build.gradle.kts | 1 + engine/build.gradle.kts | 1 + settings.gradle.kts | 2 ++ 6 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 common/.gitignore create mode 100644 common/build.gradle.kts rename {engine => common}/src/main/java/com/google/android/fhir/UnitConverter.kt (87%) diff --git a/common/.gitignore b/common/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/common/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/common/build.gradle.kts b/common/build.gradle.kts new file mode 100644 index 0000000000..6984eefc47 --- /dev/null +++ b/common/build.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id(Plugins.BuildPlugins.javaLibrary) + id(Plugins.BuildPlugins.kotlin) +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} + +dependencies { + api(Dependencies.HapiFhir.structuresR4) { exclude(module = "junit") } + implementation(Dependencies.fhirUcum) +} diff --git a/engine/src/main/java/com/google/android/fhir/UnitConverter.kt b/common/src/main/java/com/google/android/fhir/UnitConverter.kt similarity index 87% rename from engine/src/main/java/com/google/android/fhir/UnitConverter.kt rename to common/src/main/java/com/google/android/fhir/UnitConverter.kt index 32f32ca72c..dc04ed5bff 100644 --- a/engine/src/main/java/com/google/android/fhir/UnitConverter.kt +++ b/common/src/main/java/com/google/android/fhir/UnitConverter.kt @@ -24,7 +24,7 @@ import org.fhir.ucum.Pair import org.fhir.ucum.UcumEssenceService import org.fhir.ucum.UcumException -internal object UnitConverter { +object UnitConverter { private val ucumService by lazy { UcumEssenceService(this::class.java.getResourceAsStream("/ucum-essence.xml")) } @@ -38,7 +38,7 @@ internal object UnitConverter { * For example a value of 1000 mm will return 1 m. */ @Throws(ConverterException::class) - internal fun getCanonicalForm(value: UcumValue): UcumValue { + fun getCanonicalForm(value: UcumValue): UcumValue { try { val pair = ucumService.getCanonicalForm(Pair(Decimal(value.value.toPlainString()), value.code)) @@ -53,6 +53,6 @@ internal object UnitConverter { } } -internal class ConverterException(cause: Throwable) : Exception(cause) +class ConverterException(cause: Throwable) : Exception(cause) -internal data class UcumValue(val code: String, val value: BigDecimal) +data class UcumValue(val code: String, val value: BigDecimal) diff --git a/datacapture/build.gradle.kts b/datacapture/build.gradle.kts index 519a9bc2c6..555f46ddb9 100644 --- a/datacapture/build.gradle.kts +++ b/datacapture/build.gradle.kts @@ -72,6 +72,7 @@ android { configurations { all { exclude(module = "xpp3") } } dependencies { + implementation(project(mapOf("path" to ":common"))) androidTestImplementation(Dependencies.AndroidxTest.core) androidTestImplementation(Dependencies.AndroidxTest.extJunit) androidTestImplementation(Dependencies.AndroidxTest.extJunitKtx) diff --git a/engine/build.gradle.kts b/engine/build.gradle.kts index 74d4df5d96..242346c97d 100644 --- a/engine/build.gradle.kts +++ b/engine/build.gradle.kts @@ -102,6 +102,7 @@ configurations { } dependencies { + implementation(project(mapOf("path" to ":common"))) androidTestImplementation(Dependencies.AndroidxTest.core) androidTestImplementation(Dependencies.AndroidxTest.extJunitKtx) androidTestImplementation(Dependencies.AndroidxTest.runner) diff --git a/settings.gradle.kts b/settings.gradle.kts index 224ea588a7..0111cb94c7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,3 +7,5 @@ include(":engine") include(":reference") include(":codegen") + +include(":common") From bd9477ddb39d923e2bc34ec68e7ee51f72349cfb Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Wed, 20 Oct 2021 11:48:58 +0530 Subject: [PATCH 02/15] Support inequality operators > < >= <= --- .../android/fhir/datacapture/MoreTypes.kt | 86 ++++++ .../enablement/EnablementEvaluator.kt | 17 +- ...nnaireItemAutoCompleteViewHolderFactory.kt | 5 + .../android/fhir/datacapture/MoreTypesTest.kt | 245 ++++++++++++++++++ 4 files changed, 352 insertions(+), 1 deletion(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt index 02dbb05b52..f9940950e9 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt @@ -16,7 +16,13 @@ package com.google.android.fhir.datacapture +import com.google.android.fhir.datacapture.utilities.UcumValue +import com.google.android.fhir.datacapture.utilities.UnitConverter +import com.google.android.fhir.datacapture.validation.compareTo +import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.Coding +import org.hl7.fhir.r4.model.Quantity +import org.hl7.fhir.r4.model.Questionnaire import org.hl7.fhir.r4.model.Type /** @@ -38,3 +44,83 @@ internal fun equals(a: Type, b: Type): Boolean { throw NotImplementedError("Comparison for type ${a::class.java} not supported.") } + +/** True if whether at least no answer has a value that is greater than the enableWhen answer. */ +internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterThan( + questionAnswer: Type +): Boolean { + if (answer::class != questionAnswer::class || answer is BooleanType) return false + if (answer === questionAnswer) return true + if (answer.isPrimitive) return questionAnswer <= answer + if (answer is Quantity && questionAnswer is Quantity) { + val answerUcumUnit = + UnitConverter.getCanonicalForm( + UcumValue((answer as Quantity).code, (answer as Quantity).value) + ) + val questionAnswerUcumUnit = + UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) + return questionAnswerUcumUnit.value < answerUcumUnit.value + } + return false +} + +/** + * True if whether at least no answer has a value that is greater or equal to the enableWhen answer. + */ +internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterOrEqual( + questionAnswer: Type +): Boolean { + if (answer::class != questionAnswer::class || answer === questionAnswer || answer is BooleanType) + return false + if (answer.isPrimitive) return questionAnswer < answer + if (answer is Quantity && questionAnswer is Quantity) { + val answerUcumUnit = + UnitConverter.getCanonicalForm( + UcumValue((answer as Quantity).code, (answer as Quantity).value) + ) + val questionAnswerUcumUnit = + UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) + return questionAnswerUcumUnit.value < answerUcumUnit.value + } + return false +} + +/** True if whether at least no answer has a value that is less than the enableWhen answer. */ +internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessThan( + questionAnswer: Type +): Boolean { + if (answer::class != questionAnswer::class || answer is BooleanType) return false + if (answer === questionAnswer) return true + if (answer.isPrimitive) return questionAnswer >= answer + if (answer is Quantity && questionAnswer is Quantity) { + val answerUcumUnit = + UnitConverter.getCanonicalForm( + UcumValue((answer as Quantity).code, (answer as Quantity).value) + ) + val questionAnswerUcumUnit = + UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) + return questionAnswerUcumUnit.value >= answerUcumUnit.value + } + return false +} + +/** + * True if whether at least no answer has a value that is less or equal to the enableWhen answer. + */ +internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessOrEqual( + questionAnswer: Type +): Boolean { + if (answer::class != questionAnswer::class || answer === questionAnswer || answer is BooleanType) + return false + if (answer.isPrimitive) return questionAnswer > answer + if (answer is Quantity && questionAnswer is Quantity) { + val answerUcumUnit = + UnitConverter.getCanonicalForm( + UcumValue((answer as Quantity).code, (answer as Quantity).value) + ) + val questionAnswerUcumUnit = + UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) + return questionAnswerUcumUnit.value > answerUcumUnit.value + } + return false +} diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt index bfd6b1698b..8f0749a645 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt @@ -17,7 +17,10 @@ package com.google.android.fhir.datacapture.enablement import com.google.android.fhir.datacapture.equals -import java.lang.IllegalStateException +import com.google.android.fhir.datacapture.greaterOrEqual +import com.google.android.fhir.datacapture.greaterThan +import com.google.android.fhir.datacapture.lessOrEqual +import com.google.android.fhir.datacapture.lessThan import org.hl7.fhir.r4.model.Questionnaire import org.hl7.fhir.r4.model.QuestionnaireResponse @@ -127,6 +130,18 @@ private val Questionnaire.QuestionnaireItemEnableWhenComponent.predicate: Questionnaire.QuestionnaireItemOperator.NOT_EQUAL -> { !equals(it.value, answer) } + Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL -> { + greaterOrEqual(it.value) + } + Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL -> { + lessOrEqual(it.value) + } + Questionnaire.QuestionnaireItemOperator.GREATER_THAN -> { + greaterThan(it.value) + } + Questionnaire.QuestionnaireItemOperator.LESS_THAN -> { + lessThan(it.value) + } else -> throw NotImplementedError("Enable when operator $operator is not implemented.") } } diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt index 358c329501..dc46005758 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt @@ -278,5 +278,10 @@ internal object QuestionnaireItemAutoCompleteViewHolderFactory : ) } } + + private fun setViewReadOnly(view: View) { + view.isEnabled = false + view.isFocusable = false + } } } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt index 230e5396cf..76fc0e7661 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt @@ -18,11 +18,14 @@ package com.google.android.fhir.datacapture import android.os.Build import com.google.common.truth.Truth.assertThat +import java.math.BigDecimal import org.hl7.fhir.r4.model.Attachment import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.Coding import org.hl7.fhir.r4.model.DecimalType +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.Reference import org.junit.Assert.assertThrows import org.junit.Test @@ -104,4 +107,246 @@ class MoreTypesTest { assertThat(exception.message) .isEqualTo("Comparison for type ${Reference::class.java} not supported.") } + + @Test + fun greaterThan_noAnswerGreaterThanEnableAnswer_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 40 } + assertThat(enableWhen.greaterThan(answer)).isTrue() + } + + @Test + fun greaterThan_answerGreaterThanEnableAnswer_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 100 } + assertThat(enableWhen.greaterThan(answer)).isFalse() + } + + @Test + fun greaterThan_samePrimitiveValues_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.greaterThan(answer)).isTrue() + } + + @Test + fun greaterThan_nonPrimitiveValues_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } + val answer = Coding() + assertThat(enableWhen.greaterThan(answer)).isFalse() + } + + @Test + fun greaterThan_noAnswerQuantityGreaterThanEnableAnswerQuantity_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(10) + code = "h" + } + operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN + } + val answer = + Quantity().apply { + value = BigDecimal(20) + code = "min" + } + assertThat(enableWhen.greaterThan(answer)).isTrue() + } + + @Test + fun greaterOrEqual_noAnswerGreaterThanEnableAnswer_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 40 } + assertThat(enableWhen.greaterOrEqual(answer)).isTrue() + } + + @Test + fun greaterOrEqual_answerGreaterThanEnableAnswer_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 100 } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() + } + + @Test + fun greaterOrEqual_answerEqualEnableAnswer_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() + } + + @Test + fun greaterOrEqual_nonPrimitive_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } + val answer = Coding() + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() + } + + @Test + fun greaterOrEqual_answerReferenceEqualEnableAnswerReference_shouldReturnFalse() { + val answer = IntegerType().apply { value = 50 } + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { this.answer = answer } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() + } + + @Test + fun greaterOrEqual_equalQuantity_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(20) + code = "h" + } + operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN + } + val answer = + Quantity().apply { + value = BigDecimal(20) + code = "h" + } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() + } + + @Test + fun lessThan_noAnswerLessThanEnableAnswer_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 40 } + } + val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessThan(answer)).isTrue() + } + + @Test + fun lessThan_answerLessThanEnableAnswer_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 10 } + assertThat(enableWhen.lessThan(answer)).isFalse() + } + + @Test + fun lessThan_answerEqualsEnableAnswer_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessThan(answer)).isTrue() + } + + @Test + fun lessThan_nonPrimitive_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } + val answer = Coding() + assertThat(enableWhen.lessThan(answer)).isFalse() + } + + @Test + fun lessThan_noAnswerQuantityLessThanEnableAnswerQuantity_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(20) + code = "h" + } + } + val answer = + Quantity().apply { + value = BigDecimal(30) + code = "h" + } + assertThat(enableWhen.lessThan(answer)).isTrue() + } + + @Test + fun lessOrEqual_noAnswerLessOrEqualEnableAnswer_shouldReturnTrue() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 40 } + } + val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessThan(answer)).isTrue() + } + + @Test + fun lessOrEqual_answerLessOrEqualEnableAnswer_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 10 } + assertThat(enableWhen.lessOrEqual(answer)).isFalse() + } + + @Test + fun lessOrEqual_answerEqualEnableAnswer_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = IntegerType().apply { value = 50 } + } + val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessOrEqual(answer)).isFalse() + } + + @Test + fun lessOrEqual_answerReferenceEqualEnableAnswerReference_shouldReturnFalse() { + val answer = IntegerType().apply { value = 50 } + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { this.answer = answer } + assertThat(enableWhen.lessOrEqual(answer)).isFalse() + } + + @Test + fun lessOrEqual_nonPrimitive_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } + val answer = Coding() + assertThat(enableWhen.lessOrEqual(answer)).isFalse() + } + + @Test + fun lessOrEqual_sameQuantity_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(20) + code = "h" + } + } + val answer = + Quantity().apply { + value = BigDecimal(10) + code = "h" + } + assertThat(enableWhen.lessOrEqual(answer)).isFalse() + } } From 9ad0c4ef1ca25e766728182eabb1c2cace37d9cc Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Wed, 20 Oct 2021 11:52:15 +0530 Subject: [PATCH 03/15] unit converter --- .../utilities/UnitConverterUtil.kt | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt new file mode 100644 index 0000000000..fcc90f633b --- /dev/null +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2020 Google LLC + * + * 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 com.google.android.fhir.datacapture.utilities + +import java.math.BigDecimal +import java.math.MathContext +import kotlin.jvm.Throws +import org.fhir.ucum.Decimal +import org.fhir.ucum.Pair +import org.fhir.ucum.UcumEssenceService +import org.fhir.ucum.UcumException + +internal object UnitConverter { + private val ucumService by lazy { + UcumEssenceService(this::class.java.getResourceAsStream("/ucum-essence.xml")) + } + + /** + * Returns the canonical form of a Ucum Value. + * + * The canonical form is generated by normalizing [value] to UCUM base units, used to generate + * canonical matches on Quantity Search + * + * For example a value of 1000 mm will return 1 m. + */ + @Throws(ConverterException::class) + internal fun getCanonicalForm(value: UcumValue): UcumValue { + try { + val pair = + ucumService.getCanonicalForm(Pair(Decimal(value.value.toPlainString()), value.code)) + return UcumValue( + pair.code, + pair.value.asDecimal().toBigDecimal(MathContext(value.value.precision())) + ) + } catch (exception: UcumException) { + exception.printStackTrace() + throw ConverterException(exception) + } + } +} + +internal class ConverterException(cause: Throwable) : Exception(cause) + +internal data class UcumValue(val code: String, val value: BigDecimal) From e75efcf772c70778edc18e11c90394139c61238b Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Wed, 20 Oct 2021 12:20:14 +0530 Subject: [PATCH 04/15] Revert unwanted change from file. --- .../views/QuestionnaireItemAutoCompleteViewHolderFactory.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt index dc46005758..358c329501 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/views/QuestionnaireItemAutoCompleteViewHolderFactory.kt @@ -278,10 +278,5 @@ internal object QuestionnaireItemAutoCompleteViewHolderFactory : ) } } - - private fun setViewReadOnly(view: View) { - view.isEnabled = false - view.isFocusable = false - } } } From 06eab1dbc1cd6a366096153badf3641795e01273 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Wed, 20 Oct 2021 12:55:54 +0530 Subject: [PATCH 05/15] Refactoring --- .../android/fhir/datacapture/MoreTypes.kt | 18 +++----- .../enablement/EnablementEvaluator.kt | 12 ++--- .../android/fhir/datacapture/MoreTypesTest.kt | 46 ++++++++++--------- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt index f9940950e9..4892238de1 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt @@ -50,7 +50,6 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterThan( questionAnswer: Type ): Boolean { if (answer::class != questionAnswer::class || answer is BooleanType) return false - if (answer === questionAnswer) return true if (answer.isPrimitive) return questionAnswer <= answer if (answer is Quantity && questionAnswer is Quantity) { val answerUcumUnit = @@ -59,19 +58,18 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterThan( ) val questionAnswerUcumUnit = UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - return questionAnswerUcumUnit.value < answerUcumUnit.value + return questionAnswerUcumUnit.value <= answerUcumUnit.value } return false } /** - * True if whether at least no answer has a value that is greater or equal to the enableWhen answer. + * Returns true if whether no answer has a value that is greater or equal to the enableWhen answer. */ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterOrEqual( questionAnswer: Type ): Boolean { - if (answer::class != questionAnswer::class || answer === questionAnswer || answer is BooleanType) - return false + if (answer::class != questionAnswer::class || answer is BooleanType) return false if (answer.isPrimitive) return questionAnswer < answer if (answer is Quantity && questionAnswer is Quantity) { val answerUcumUnit = @@ -85,12 +83,11 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterOrEqual( return false } -/** True if whether at least no answer has a value that is less than the enableWhen answer. */ +/** Returns true if whether no answer has a value that is less than the enableWhen answer. */ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessThan( questionAnswer: Type ): Boolean { if (answer::class != questionAnswer::class || answer is BooleanType) return false - if (answer === questionAnswer) return true if (answer.isPrimitive) return questionAnswer >= answer if (answer is Quantity && questionAnswer is Quantity) { val answerUcumUnit = @@ -104,14 +101,11 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessThan( return false } -/** - * True if whether at least no answer has a value that is less or equal to the enableWhen answer. - */ +/** Returns true if whether no answer has a value that is less or equal to the enableWhen answer. */ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessOrEqual( questionAnswer: Type ): Boolean { - if (answer::class != questionAnswer::class || answer === questionAnswer || answer is BooleanType) - return false + if (answer::class != questionAnswer::class || answer is BooleanType) return false if (answer.isPrimitive) return questionAnswer > answer if (answer is Quantity && questionAnswer is Quantity) { val answerUcumUnit = diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt index 8f0749a645..e23e7dfd1e 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt @@ -130,18 +130,18 @@ private val Questionnaire.QuestionnaireItemEnableWhenComponent.predicate: Questionnaire.QuestionnaireItemOperator.NOT_EQUAL -> { !equals(it.value, answer) } - Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL -> { - greaterOrEqual(it.value) - } - Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL -> { - lessOrEqual(it.value) - } Questionnaire.QuestionnaireItemOperator.GREATER_THAN -> { greaterThan(it.value) } + Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL -> { + greaterOrEqual(it.value) + } Questionnaire.QuestionnaireItemOperator.LESS_THAN -> { lessThan(it.value) } + Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL -> { + lessOrEqual(it.value) + } else -> throw NotImplementedError("Enable when operator $operator is not implemented.") } } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt index 76fc0e7661..8a0247c20b 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt @@ -115,6 +115,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 40 } + assertThat(enableWhen.greaterThan(answer)).isTrue() } @@ -125,16 +126,18 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 100 } + assertThat(enableWhen.greaterThan(answer)).isFalse() } @Test - fun greaterThan_samePrimitiveValues_shouldReturnTrue() { + fun greaterThan_answerEqualEnableAnswer_shouldReturnTrue() { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.greaterThan(answer)).isTrue() } @@ -143,6 +146,7 @@ class MoreTypesTest { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } val answer = Coding() + assertThat(enableWhen.greaterThan(answer)).isFalse() } @@ -162,6 +166,7 @@ class MoreTypesTest { value = BigDecimal(20) code = "min" } + assertThat(enableWhen.greaterThan(answer)).isTrue() } @@ -172,16 +177,18 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 40 } + assertThat(enableWhen.greaterOrEqual(answer)).isTrue() } @Test - fun greaterOrEqual_answerGreaterThanEnableAnswer_shouldReturnTrue() { + fun greaterOrEqual_answerGreaterThanEnableAnswer_shouldReturnFalse() { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 100 } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() } @@ -192,6 +199,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() } @@ -200,19 +208,12 @@ class MoreTypesTest { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } val answer = Coding() - assertThat(enableWhen.greaterOrEqual(answer)).isFalse() - } - @Test - fun greaterOrEqual_answerReferenceEqualEnableAnswerReference_shouldReturnFalse() { - val answer = IntegerType().apply { value = 50 } - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { this.answer = answer } assertThat(enableWhen.greaterOrEqual(answer)).isFalse() } @Test - fun greaterOrEqual_equalQuantity_shouldReturnFalse() { + fun greaterOrEqual_AnswerQuantityGreaterThanEnableAnswerQuantity_shouldReturnFalse() { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = @@ -224,9 +225,10 @@ class MoreTypesTest { } val answer = Quantity().apply { - value = BigDecimal(20) + value = BigDecimal(30) code = "h" } + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() } @@ -237,6 +239,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 40 } } val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessThan(answer)).isTrue() } @@ -247,6 +250,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 10 } + assertThat(enableWhen.lessThan(answer)).isFalse() } @@ -257,6 +261,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessThan(answer)).isTrue() } @@ -265,6 +270,7 @@ class MoreTypesTest { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } val answer = Coding() + assertThat(enableWhen.lessThan(answer)).isFalse() } @@ -283,6 +289,7 @@ class MoreTypesTest { value = BigDecimal(30) code = "h" } + assertThat(enableWhen.lessThan(answer)).isTrue() } @@ -293,6 +300,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 40 } } val answer = IntegerType().apply { value = 50 } + assertThat(enableWhen.lessThan(answer)).isTrue() } @@ -303,6 +311,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 10 } + assertThat(enableWhen.lessOrEqual(answer)).isFalse() } @@ -313,14 +322,7 @@ class MoreTypesTest { answer = IntegerType().apply { value = 50 } } val answer = IntegerType().apply { value = 50 } - assertThat(enableWhen.lessOrEqual(answer)).isFalse() - } - @Test - fun lessOrEqual_answerReferenceEqualEnableAnswerReference_shouldReturnFalse() { - val answer = IntegerType().apply { value = 50 } - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { this.answer = answer } assertThat(enableWhen.lessOrEqual(answer)).isFalse() } @@ -329,11 +331,12 @@ class MoreTypesTest { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } val answer = Coding() + assertThat(enableWhen.lessOrEqual(answer)).isFalse() } @Test - fun lessOrEqual_sameQuantity_shouldReturnFalse() { + fun lessOrEqual_noAnswerQuantityLessThanOrEqualEnableAnswerQuantity_shouldReturnTrue() { val enableWhen = Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = @@ -344,9 +347,10 @@ class MoreTypesTest { } val answer = Quantity().apply { - value = BigDecimal(10) + value = BigDecimal(30) code = "h" } - assertThat(enableWhen.lessOrEqual(answer)).isFalse() + + assertThat(enableWhen.lessOrEqual(answer)).isTrue() } } From 06d4aeb599bf102f278a5563bb7a3307e1ef9af6 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Wed, 20 Oct 2021 13:07:11 +0530 Subject: [PATCH 06/15] api doc --- .../java/com/google/android/fhir/datacapture/MoreTypes.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt index 4892238de1..54bbab94cc 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt @@ -45,7 +45,10 @@ internal fun equals(a: Type, b: Type): Boolean { throw NotImplementedError("Comparison for type ${a::class.java} not supported.") } -/** True if whether at least no answer has a value that is greater than the enableWhen answer. */ +/** + * Returns true if whether at least no answer has a value that is greater than the enableWhen + * answer. + */ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterThan( questionAnswer: Type ): Boolean { From df1d3d677aa40df7220452cf53b08ae6b78cbb91 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 21 Oct 2021 17:07:41 +0530 Subject: [PATCH 07/15] Tests quantity with different units --- .../android/fhir/datacapture/MoreTypes.kt | 16 +++- .../android/fhir/datacapture/MoreTypesTest.kt | 77 +++++++++++++++++++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt index 54bbab94cc..62ebf514f0 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt @@ -61,7 +61,9 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterThan( ) val questionAnswerUcumUnit = UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - return questionAnswerUcumUnit.value <= answerUcumUnit.value + if (answerUcumUnit.code == questionAnswerUcumUnit.code) { + return questionAnswerUcumUnit.value <= answerUcumUnit.value + } } return false } @@ -81,7 +83,9 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterOrEqual( ) val questionAnswerUcumUnit = UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - return questionAnswerUcumUnit.value < answerUcumUnit.value + if (answerUcumUnit.code == questionAnswerUcumUnit.code) { + return questionAnswerUcumUnit.value < answerUcumUnit.value + } } return false } @@ -99,7 +103,9 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessThan( ) val questionAnswerUcumUnit = UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - return questionAnswerUcumUnit.value >= answerUcumUnit.value + if (answerUcumUnit.code == questionAnswerUcumUnit.code) { + return questionAnswerUcumUnit.value >= answerUcumUnit.value + } } return false } @@ -117,7 +123,9 @@ internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessOrEqual( ) val questionAnswerUcumUnit = UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - return questionAnswerUcumUnit.value > answerUcumUnit.value + if (answerUcumUnit.code == questionAnswerUcumUnit.code) { + return questionAnswerUcumUnit.value > answerUcumUnit.value + } } return false } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt index 8a0247c20b..3ae95bb6e0 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt @@ -170,6 +170,26 @@ class MoreTypesTest { assertThat(enableWhen.greaterThan(answer)).isTrue() } + @Test + fun greaterThan_differentQuantityUnits_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(10) + code = "h" + } + operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN + } + val answer = + Quantity().apply { + value = BigDecimal(10) + code = "kg" + } + + assertThat(enableWhen.greaterThan(answer)).isFalse() + } + @Test fun greaterOrEqual_noAnswerGreaterThanEnableAnswer_shouldReturnTrue() { val enableWhen = @@ -232,6 +252,25 @@ class MoreTypesTest { assertThat(enableWhen.greaterOrEqual(answer)).isFalse() } + @Test + fun greaterOrEqual_differentQuantityUnits_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(20) + code = "h" + } + } + val answer = + Quantity().apply { + value = BigDecimal(10) + code = "kg" + } + + assertThat(enableWhen.greaterOrEqual(answer)).isFalse() + } + @Test fun lessThan_noAnswerLessThanEnableAnswer_shouldReturnTrue() { val enableWhen = @@ -293,6 +332,25 @@ class MoreTypesTest { assertThat(enableWhen.lessThan(answer)).isTrue() } + @Test + fun lessThan_differentQuantityUnits_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(20) + code = "h" + } + } + val answer = + Quantity().apply { + value = BigDecimal(30) + code = "kg" + } + + assertThat(enableWhen.lessThan(answer)).isFalse() + } + @Test fun lessOrEqual_noAnswerLessOrEqualEnableAnswer_shouldReturnTrue() { val enableWhen = @@ -353,4 +411,23 @@ class MoreTypesTest { assertThat(enableWhen.lessOrEqual(answer)).isTrue() } + + @Test + fun lessOrEqual_differentQuantityUnits_shouldReturnFalse() { + val enableWhen = + Questionnaire.QuestionnaireItemEnableWhenComponent().apply { + answer = + answerQuantity.apply { + value = BigDecimal(20) + code = "h" + } + } + val answer = + Quantity().apply { + value = BigDecimal(30) + code = "kg" + } + + assertThat(enableWhen.lessOrEqual(answer)).isFalse() + } } From 64cb0ad002cdbaccd2a700262b9d8e8d7dfae426 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 21 Oct 2021 17:32:59 +0530 Subject: [PATCH 08/15] Remove UnitConverter file datacapture --- .../android/fhir/datacapture/MoreTypes.kt | 4 +- .../utilities/UnitConverterUtil.kt | 58 ------------------- 2 files changed, 2 insertions(+), 60 deletions(-) delete mode 100644 datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt index 62ebf514f0..8d0e9da19f 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt @@ -16,8 +16,8 @@ package com.google.android.fhir.datacapture -import com.google.android.fhir.datacapture.utilities.UcumValue -import com.google.android.fhir.datacapture.utilities.UnitConverter +import com.google.android.fhir.UcumValue +import com.google.android.fhir.UnitConverter import com.google.android.fhir.datacapture.validation.compareTo import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.Coding diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt deleted file mode 100644 index fcc90f633b..0000000000 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/utilities/UnitConverterUtil.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2020 Google LLC - * - * 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 com.google.android.fhir.datacapture.utilities - -import java.math.BigDecimal -import java.math.MathContext -import kotlin.jvm.Throws -import org.fhir.ucum.Decimal -import org.fhir.ucum.Pair -import org.fhir.ucum.UcumEssenceService -import org.fhir.ucum.UcumException - -internal object UnitConverter { - private val ucumService by lazy { - UcumEssenceService(this::class.java.getResourceAsStream("/ucum-essence.xml")) - } - - /** - * Returns the canonical form of a Ucum Value. - * - * The canonical form is generated by normalizing [value] to UCUM base units, used to generate - * canonical matches on Quantity Search - * - * For example a value of 1000 mm will return 1 m. - */ - @Throws(ConverterException::class) - internal fun getCanonicalForm(value: UcumValue): UcumValue { - try { - val pair = - ucumService.getCanonicalForm(Pair(Decimal(value.value.toPlainString()), value.code)) - return UcumValue( - pair.code, - pair.value.asDecimal().toBigDecimal(MathContext(value.value.precision())) - ) - } catch (exception: UcumException) { - exception.printStackTrace() - throw ConverterException(exception) - } - } -} - -internal class ConverterException(cause: Throwable) : Exception(cause) - -internal data class UcumValue(val code: String, val value: BigDecimal) From 8f781c2169b2a10870da7a05e254bb7bedaf424b Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Tue, 16 Nov 2021 16:54:17 +0530 Subject: [PATCH 09/15] Undo changes. --- .../android/fhir/datacapture/MoreTypes.kt | 91 ----- .../enablement/EnablementEvaluator.kt | 17 +- .../android/fhir/datacapture/MoreTypesTest.kt | 326 ------------------ 3 files changed, 1 insertion(+), 433 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt index 8d0e9da19f..02dbb05b52 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/MoreTypes.kt @@ -16,13 +16,7 @@ package com.google.android.fhir.datacapture -import com.google.android.fhir.UcumValue -import com.google.android.fhir.UnitConverter -import com.google.android.fhir.datacapture.validation.compareTo -import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.Coding -import org.hl7.fhir.r4.model.Quantity -import org.hl7.fhir.r4.model.Questionnaire import org.hl7.fhir.r4.model.Type /** @@ -44,88 +38,3 @@ internal fun equals(a: Type, b: Type): Boolean { throw NotImplementedError("Comparison for type ${a::class.java} not supported.") } - -/** - * Returns true if whether at least no answer has a value that is greater than the enableWhen - * answer. - */ -internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterThan( - questionAnswer: Type -): Boolean { - if (answer::class != questionAnswer::class || answer is BooleanType) return false - if (answer.isPrimitive) return questionAnswer <= answer - if (answer is Quantity && questionAnswer is Quantity) { - val answerUcumUnit = - UnitConverter.getCanonicalForm( - UcumValue((answer as Quantity).code, (answer as Quantity).value) - ) - val questionAnswerUcumUnit = - UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - if (answerUcumUnit.code == questionAnswerUcumUnit.code) { - return questionAnswerUcumUnit.value <= answerUcumUnit.value - } - } - return false -} - -/** - * Returns true if whether no answer has a value that is greater or equal to the enableWhen answer. - */ -internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.greaterOrEqual( - questionAnswer: Type -): Boolean { - if (answer::class != questionAnswer::class || answer is BooleanType) return false - if (answer.isPrimitive) return questionAnswer < answer - if (answer is Quantity && questionAnswer is Quantity) { - val answerUcumUnit = - UnitConverter.getCanonicalForm( - UcumValue((answer as Quantity).code, (answer as Quantity).value) - ) - val questionAnswerUcumUnit = - UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - if (answerUcumUnit.code == questionAnswerUcumUnit.code) { - return questionAnswerUcumUnit.value < answerUcumUnit.value - } - } - return false -} - -/** Returns true if whether no answer has a value that is less than the enableWhen answer. */ -internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessThan( - questionAnswer: Type -): Boolean { - if (answer::class != questionAnswer::class || answer is BooleanType) return false - if (answer.isPrimitive) return questionAnswer >= answer - if (answer is Quantity && questionAnswer is Quantity) { - val answerUcumUnit = - UnitConverter.getCanonicalForm( - UcumValue((answer as Quantity).code, (answer as Quantity).value) - ) - val questionAnswerUcumUnit = - UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - if (answerUcumUnit.code == questionAnswerUcumUnit.code) { - return questionAnswerUcumUnit.value >= answerUcumUnit.value - } - } - return false -} - -/** Returns true if whether no answer has a value that is less or equal to the enableWhen answer. */ -internal fun Questionnaire.QuestionnaireItemEnableWhenComponent.lessOrEqual( - questionAnswer: Type -): Boolean { - if (answer::class != questionAnswer::class || answer is BooleanType) return false - if (answer.isPrimitive) return questionAnswer > answer - if (answer is Quantity && questionAnswer is Quantity) { - val answerUcumUnit = - UnitConverter.getCanonicalForm( - UcumValue((answer as Quantity).code, (answer as Quantity).value) - ) - val questionAnswerUcumUnit = - UnitConverter.getCanonicalForm(UcumValue(questionAnswer.code, questionAnswer.value)) - if (answerUcumUnit.code == questionAnswerUcumUnit.code) { - return questionAnswerUcumUnit.value > answerUcumUnit.value - } - } - return false -} diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt index e23e7dfd1e..bfd6b1698b 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt @@ -17,10 +17,7 @@ package com.google.android.fhir.datacapture.enablement import com.google.android.fhir.datacapture.equals -import com.google.android.fhir.datacapture.greaterOrEqual -import com.google.android.fhir.datacapture.greaterThan -import com.google.android.fhir.datacapture.lessOrEqual -import com.google.android.fhir.datacapture.lessThan +import java.lang.IllegalStateException import org.hl7.fhir.r4.model.Questionnaire import org.hl7.fhir.r4.model.QuestionnaireResponse @@ -130,18 +127,6 @@ private val Questionnaire.QuestionnaireItemEnableWhenComponent.predicate: Questionnaire.QuestionnaireItemOperator.NOT_EQUAL -> { !equals(it.value, answer) } - Questionnaire.QuestionnaireItemOperator.GREATER_THAN -> { - greaterThan(it.value) - } - Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL -> { - greaterOrEqual(it.value) - } - Questionnaire.QuestionnaireItemOperator.LESS_THAN -> { - lessThan(it.value) - } - Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL -> { - lessOrEqual(it.value) - } else -> throw NotImplementedError("Enable when operator $operator is not implemented.") } } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt index 3ae95bb6e0..230e5396cf 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/MoreTypesTest.kt @@ -18,14 +18,11 @@ package com.google.android.fhir.datacapture import android.os.Build import com.google.common.truth.Truth.assertThat -import java.math.BigDecimal import org.hl7.fhir.r4.model.Attachment import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.Coding import org.hl7.fhir.r4.model.DecimalType -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.Reference import org.junit.Assert.assertThrows import org.junit.Test @@ -107,327 +104,4 @@ class MoreTypesTest { assertThat(exception.message) .isEqualTo("Comparison for type ${Reference::class.java} not supported.") } - - @Test - fun greaterThan_noAnswerGreaterThanEnableAnswer_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 40 } - - assertThat(enableWhen.greaterThan(answer)).isTrue() - } - - @Test - fun greaterThan_answerGreaterThanEnableAnswer_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 100 } - - assertThat(enableWhen.greaterThan(answer)).isFalse() - } - - @Test - fun greaterThan_answerEqualEnableAnswer_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 50 } - - assertThat(enableWhen.greaterThan(answer)).isTrue() - } - - @Test - fun greaterThan_nonPrimitiveValues_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } - val answer = Coding() - - assertThat(enableWhen.greaterThan(answer)).isFalse() - } - - @Test - fun greaterThan_noAnswerQuantityGreaterThanEnableAnswerQuantity_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(10) - code = "h" - } - operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN - } - val answer = - Quantity().apply { - value = BigDecimal(20) - code = "min" - } - - assertThat(enableWhen.greaterThan(answer)).isTrue() - } - - @Test - fun greaterThan_differentQuantityUnits_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(10) - code = "h" - } - operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN - } - val answer = - Quantity().apply { - value = BigDecimal(10) - code = "kg" - } - - assertThat(enableWhen.greaterThan(answer)).isFalse() - } - - @Test - fun greaterOrEqual_noAnswerGreaterThanEnableAnswer_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 40 } - - assertThat(enableWhen.greaterOrEqual(answer)).isTrue() - } - - @Test - fun greaterOrEqual_answerGreaterThanEnableAnswer_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 100 } - - assertThat(enableWhen.greaterOrEqual(answer)).isFalse() - } - - @Test - fun greaterOrEqual_answerEqualEnableAnswer_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 50 } - - assertThat(enableWhen.greaterOrEqual(answer)).isFalse() - } - - @Test - fun greaterOrEqual_nonPrimitive_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } - val answer = Coding() - - assertThat(enableWhen.greaterOrEqual(answer)).isFalse() - } - - @Test - fun greaterOrEqual_AnswerQuantityGreaterThanEnableAnswerQuantity_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(20) - code = "h" - } - operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN - } - val answer = - Quantity().apply { - value = BigDecimal(30) - code = "h" - } - - assertThat(enableWhen.greaterOrEqual(answer)).isFalse() - } - - @Test - fun greaterOrEqual_differentQuantityUnits_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(20) - code = "h" - } - } - val answer = - Quantity().apply { - value = BigDecimal(10) - code = "kg" - } - - assertThat(enableWhen.greaterOrEqual(answer)).isFalse() - } - - @Test - fun lessThan_noAnswerLessThanEnableAnswer_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 40 } - } - val answer = IntegerType().apply { value = 50 } - - assertThat(enableWhen.lessThan(answer)).isTrue() - } - - @Test - fun lessThan_answerLessThanEnableAnswer_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 10 } - - assertThat(enableWhen.lessThan(answer)).isFalse() - } - - @Test - fun lessThan_answerEqualsEnableAnswer_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 50 } - - assertThat(enableWhen.lessThan(answer)).isTrue() - } - - @Test - fun lessThan_nonPrimitive_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } - val answer = Coding() - - assertThat(enableWhen.lessThan(answer)).isFalse() - } - - @Test - fun lessThan_noAnswerQuantityLessThanEnableAnswerQuantity_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(20) - code = "h" - } - } - val answer = - Quantity().apply { - value = BigDecimal(30) - code = "h" - } - - assertThat(enableWhen.lessThan(answer)).isTrue() - } - - @Test - fun lessThan_differentQuantityUnits_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(20) - code = "h" - } - } - val answer = - Quantity().apply { - value = BigDecimal(30) - code = "kg" - } - - assertThat(enableWhen.lessThan(answer)).isFalse() - } - - @Test - fun lessOrEqual_noAnswerLessOrEqualEnableAnswer_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 40 } - } - val answer = IntegerType().apply { value = 50 } - - assertThat(enableWhen.lessThan(answer)).isTrue() - } - - @Test - fun lessOrEqual_answerLessOrEqualEnableAnswer_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 10 } - - assertThat(enableWhen.lessOrEqual(answer)).isFalse() - } - - @Test - fun lessOrEqual_answerEqualEnableAnswer_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = IntegerType().apply { value = 50 } - } - val answer = IntegerType().apply { value = 50 } - - assertThat(enableWhen.lessOrEqual(answer)).isFalse() - } - - @Test - fun lessOrEqual_nonPrimitive_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { answer = Coding() } - val answer = Coding() - - assertThat(enableWhen.lessOrEqual(answer)).isFalse() - } - - @Test - fun lessOrEqual_noAnswerQuantityLessThanOrEqualEnableAnswerQuantity_shouldReturnTrue() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(20) - code = "h" - } - } - val answer = - Quantity().apply { - value = BigDecimal(30) - code = "h" - } - - assertThat(enableWhen.lessOrEqual(answer)).isTrue() - } - - @Test - fun lessOrEqual_differentQuantityUnits_shouldReturnFalse() { - val enableWhen = - Questionnaire.QuestionnaireItemEnableWhenComponent().apply { - answer = - answerQuantity.apply { - value = BigDecimal(20) - code = "h" - } - } - val answer = - Quantity().apply { - value = BigDecimal(30) - code = "kg" - } - - assertThat(enableWhen.lessOrEqual(answer)).isFalse() - } } From 90f4327d293cecbf1cbd4beae3c32eb1182d3c6a Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 18 Nov 2021 14:57:15 +0530 Subject: [PATCH 10/15] Review changes. --- .../java/com/google/android/fhir/MoreTypes.kt | 13 ++ .../enablement/EnablementEvaluator.kt | 21 +++ .../enablement/EnablementEvaluatorTest.kt | 133 ++++++++++++++++++ 3 files changed, 167 insertions(+) diff --git a/common/src/main/java/com/google/android/fhir/MoreTypes.kt b/common/src/main/java/com/google/android/fhir/MoreTypes.kt index 49190f007c..351d2767cf 100644 --- a/common/src/main/java/com/google/android/fhir/MoreTypes.kt +++ b/common/src/main/java/com/google/android/fhir/MoreTypes.kt @@ -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 /** @@ -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") -> { + 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() } diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt index 4c1a47d956..6b7aacf2fb 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt @@ -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 @@ -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.") } } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt index 2397922c2f..3348eed39a 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt @@ -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 @@ -383,6 +385,137 @@ class EnablementEvaluatorTest { .isFalse() } + @Test + 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 { + 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). * From 554c82be8e871792e2ad9019502d436258f9bfb8 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 18 Nov 2021 16:13:20 +0530 Subject: [PATCH 11/15] update test --- ...antityViewHolderFactoryInstrumentedTest.kt | 29 ------------------- .../enablement/EnablementEvaluator.kt | 8 ++--- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextQuantityViewHolderFactoryInstrumentedTest.kt b/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextQuantityViewHolderFactoryInstrumentedTest.kt index 4707fb4817..1fa9b5dca2 100644 --- a/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextQuantityViewHolderFactoryInstrumentedTest.kt +++ b/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextQuantityViewHolderFactoryInstrumentedTest.kt @@ -28,7 +28,6 @@ import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.google.common.truth.Truth.assertThat import java.math.BigDecimal -import kotlin.test.assertFailsWith import org.hl7.fhir.r4.model.Quantity import org.hl7.fhir.r4.model.Questionnaire import org.hl7.fhir.r4.model.QuestionnaireResponse @@ -189,34 +188,6 @@ class QuestionnaireItemEditTextQuantityViewHolderFactoryInstrumentedTest { assertThat(questionnaireItemViewItem.questionnaireResponseItem.answer.size).isEqualTo(0) } - @Test - @UiThreadTest - fun displayValidationResult_shouldThrowNotImplementedError() { - assertFailsWith { - viewHolder.bind( - QuestionnaireItemViewItem( - Questionnaire.QuestionnaireItemComponent().apply { - addExtension().apply { - url = "http://hl7.org/fhir/StructureDefinition/minValue" - setValue(Quantity(2.2)) - } - addExtension().apply { - url = "http://hl7.org/fhir/StructureDefinition/maxValue" - setValue(Quantity(4.4)) - } - }, - QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { - addAnswer( - QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply { - value = Quantity(3.3) - } - ) - } - ) {} - ) - } - } - @Test @UiThreadTest fun displayValidationResult_error_shouldShowErrorMessage() { diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt index 6b7aacf2fb..1f50c7660b 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt @@ -129,22 +129,22 @@ private val Questionnaire.QuestionnaireItemEnableWhenComponent.predicate: !equals(it.value, answer) } Questionnaire.QuestionnaireItemOperator.GREATER_THAN -> { - // True if whether at least no answer has a value that is greater than the enableWhen + // 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 + // 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 + // 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 + // True if whether at least no answer has a value that is less or equal to the // enableWhen answer. answer < it.value } From 000fa9e1400677fa7d551657acacebb4fc1d8433 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Fri, 19 Nov 2021 12:08:17 +0530 Subject: [PATCH 12/15] Update operators. --- .../enablement/EnablementEvaluator.kt | 17 +++------ .../enablement/EnablementEvaluatorTest.kt | 36 +++++++++---------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt index 1f50c7660b..700f79d45a 100644 --- a/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt +++ b/datacapture/src/main/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluator.kt @@ -18,7 +18,6 @@ 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 import org.hl7.fhir.r4.model.QuestionnaireResponse @@ -129,24 +128,16 @@ private val Questionnaire.QuestionnaireItemEnableWhenComponent.predicate: !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 + it.value > answer } 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 + it.value >= answer } Questionnaire.QuestionnaireItemOperator.LESS_THAN -> { - // True if whether at least no answer has a value that is less than the enableWhen - // answer. - answer <= it.value + it.value < answer } 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 + it.value <= answer } else -> throw NotImplementedError("Enable when operator $operator is not implemented.") } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt index 3348eed39a..df5078a358 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt @@ -386,117 +386,117 @@ class EnablementEvaluatorTest { } @Test - fun evaluate_greaterThan_noAnswersGreaterThanEnableWhenAnswer_shouldReturnTrue() { + fun evaluate_greaterThan_answersGreaterThanEnableWhenAnswer_shouldReturnTrue() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN, expected = IntegerType(10), - actual = listOf(IntegerType(5)) + actual = listOf(IntegerType(20)) ) ) .isTrue() } @Test - fun evaluate_greaterThan_answersGreaterThanEnableWhenAnswer_shouldReturnFalse() { + fun evaluate_greaterThan_noAnswersGreaterThanEnableWhenAnswer_shouldReturnFalse() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN, expected = IntegerType(10), - actual = listOf(IntegerType(20)) + actual = listOf(IntegerType(5)) ) ) .isFalse() } @Test - fun evaluate_greaterOrEqual_noAnswersGreaterOrEqualEnableWhenAnswer_shouldReturnTrue() { + fun evaluate_greaterOrEqual_answersGreaterOrEqualEnableWhenAnswer_shouldReturnTrue() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL, expected = IntegerType(10), - actual = listOf(IntegerType(5)) + actual = listOf(IntegerType(10)) ) ) .isTrue() } @Test - fun evaluate_greaterOrEqual_answersGreaterOrEqualEnableWhenAnswer_shouldReturnFalse() { + fun evaluate_greaterOrEqual_noAnswersGreaterOrEqualEnableWhenAnswer_shouldReturnFalse() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL, expected = IntegerType(10), - actual = listOf(IntegerType(10)) + actual = listOf(IntegerType(5)) ) ) .isFalse() } @Test - fun evaluate_lessThan_noAnswersLessThanEnableWhenAnswer_shouldReturnTrue() { + fun evaluate_lessThan_answersLessThanEnableWhenAnswer_shouldReturnTrue() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN, expected = IntegerType(10), - actual = listOf(IntegerType(20)) + actual = listOf(IntegerType(5)) ) ) .isTrue() } @Test - fun evaluate_lessThan_answersLessThanEnableWhenAnswer_shouldReturnFalse() { + fun evaluate_lessThan_noAnswersLessThanEnableWhenAnswer_shouldReturnFalse() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN, expected = IntegerType(10), - actual = listOf(IntegerType(5)) + actual = listOf(IntegerType(20)) ) ) .isFalse() } @Test - fun evaluate_lessOrEqual_noAnswerLessOrEqualEnableWhenAnswer_shouldReturnTrue() { + fun evaluate_lessOrEqual_answerLessOrEqualEnableWhenAnswer_shouldReturnTrue() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, expected = IntegerType(10), - actual = listOf(IntegerType(20)) + actual = listOf(IntegerType(10)) ) ) .isTrue() } @Test - fun evaluate_lessOrEqual_answerLessOrEqualEnableWhenAnswer_shouldReturnFalse() { + fun evaluate_lessOrEqual_noAnswerLessOrEqualEnableWhenAnswer_shouldReturnFalse() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, expected = IntegerType(10), - actual = listOf(IntegerType(10)) + actual = listOf(IntegerType(20)) ) ) .isFalse() } @Test - fun evaluate_quantityType_lessOrEqual_noAnswerLessOrEqualEnableWhenAnswer_shouldReturnTrue() { + fun evaluate_quantityType_lessOrEqual_answerLessOrEqualEnableWhenAnswer_shouldReturnTrue() { evaluateEnableWhen( behavior = null, EnableWhen( operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, expected = Quantity().setCode("h").setValue(10), - actual = listOf(Quantity().setCode("h").setValue(20)) + actual = listOf(Quantity().setCode("h").setValue(5)) ) ) .isTrue() From 196978fed83db535e6dfbbcd3d9de145410bb827 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Tue, 23 Nov 2021 12:27:43 +0530 Subject: [PATCH 13/15] Review comment changes. --- common/build.gradle.kts | 1 + .../com/google/android/fhir/MoreTypesTest.kt | 34 +++++++++++++++++++ .../enablement/EnablementEvaluatorTest.kt | 29 ---------------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 08ffdce5d4..19bcf3a0e1 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { api(Dependencies.HapiFhir.structuresR4) implementation(Dependencies.fhirUcum) + implementation(Dependencies.Kotlin.kotlinTestJunit) testImplementation(Dependencies.AndroidxTest.core) testImplementation(Dependencies.junit) diff --git a/common/src/test/java/com/google/android/fhir/MoreTypesTest.kt b/common/src/test/java/com/google/android/fhir/MoreTypesTest.kt index 4885faf67e..ade1db061b 100644 --- a/common/src/test/java/com/google/android/fhir/MoreTypesTest.kt +++ b/common/src/test/java/com/google/android/fhir/MoreTypesTest.kt @@ -19,6 +19,7 @@ package com.google.android.fhir import android.os.Build import com.google.common.truth.Truth.assertThat import java.util.Calendar +import kotlin.test.assertFailsWith import org.hl7.fhir.r4.model.Attachment import org.hl7.fhir.r4.model.BooleanType import org.hl7.fhir.r4.model.Coding @@ -204,4 +205,37 @@ class MoreTypesTest { assertThat(exception.message) .isEqualTo("Cannot compare different data types: decimal and integer") } + + @Test + fun compareTo_quantityType_shouldReturnPositiveValue() { + val value = Quantity().setCode("h").setValue(10) + val otherValue = Quantity().setCode("h").setValue(5) + + assertThat(value.compareTo(otherValue)).isEqualTo(1) + } + + @Test + fun compareTo_quantityType_shouldReturnZero() { + val value = Quantity().setCode("h").setValue(10) + val otherValue = Quantity().setCode("h").setValue(10) + + assertThat(value.compareTo(otherValue)).isEqualTo(0) + } + + @Test + fun compareTo_quantityType_shouldReturnNegativeValue() { + val value = Quantity().setCode("h").setValue(10) + val otherValue = Quantity().setCode("h").setValue(20) + + assertThat(value.compareTo(otherValue)).isEqualTo(-1) + } + + @Test + fun compareTo_quantityWithDifferentCodes_shouldFail() { + assertFailsWith { + val value = Quantity().setCode("h").setValue(10) + val otherValue = Quantity().setCode("kg").setValue(5) + value.compareTo(otherValue) + } + } } diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt index df5078a358..4090eb62a1 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt @@ -19,11 +19,9 @@ 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 @@ -489,33 +487,6 @@ class EnablementEvaluatorTest { .isFalse() } - @Test - fun evaluate_quantityType_lessOrEqual_answerLessOrEqualEnableWhenAnswer_shouldReturnTrue() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, - expected = Quantity().setCode("h").setValue(10), - actual = listOf(Quantity().setCode("h").setValue(5)) - ) - ) - .isTrue() - } - - @Test - fun evaluate_quantityWithDifferentCodes_shouldFail() { - assertFailsWith { - 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). * From 40b19077c8b73809765ff0f6924d0952ae038df9 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 25 Nov 2021 13:02:42 +0530 Subject: [PATCH 14/15] Review comment code changes. --- .../java/com/google/android/fhir/MoreTypes.kt | 65 +++--- .../enablement/EnablementEvaluatorTest.kt | 208 +++++++++--------- 2 files changed, 135 insertions(+), 138 deletions(-) diff --git a/common/src/main/java/com/google/android/fhir/MoreTypes.kt b/common/src/main/java/com/google/android/fhir/MoreTypes.kt index 351d2767cf..868b7a0a4b 100644 --- a/common/src/main/java/com/google/android/fhir/MoreTypes.kt +++ b/common/src/main/java/com/google/android/fhir/MoreTypes.kt @@ -42,42 +42,39 @@ fun equals(a: Type, b: Type): Boolean { throw NotImplementedError("Comparison for type ${a::class.java} not supported.") } -operator fun Type.compareTo(value: Type?): Int { - if (value != null) { - if (!this.fhirType().equals(value.fhirType())) { - throw IllegalArgumentException( - "Cannot compare different data types: ${this.fhirType()} and ${value.fhirType()}" - ) +operator fun Type.compareTo(value: Type): Int { + if (!this.fhirType().equals(value.fhirType())) { + throw IllegalArgumentException( + "Cannot compare different data types: ${this.fhirType()} and ${value.fhirType()}" + ) + } + when { + this.fhirType().equals("integer") -> { + return this.primitiveValue().toInt().compareTo(value.primitiveValue().toInt()) } - when { - this.fhirType().equals("integer") -> { - return this.primitiveValue().toInt().compareTo(value.primitiveValue().toInt()) - } - this.fhirType().equals("decimal") -> { - return this.primitiveValue().toBigDecimal().compareTo(value.primitiveValue().toBigDecimal()) - } - this.fhirType().equals("date") -> { - return clearTimeFromDateValue(this.dateTimeValue().value) - .compareTo(clearTimeFromDateValue(value.dateTimeValue().value)) - } - this.fhirType().equals("dateTime") -> { - return this.dateTimeValue().value.compareTo(value.dateTimeValue().value) - } - this.fhirType().equals("Quantity") -> { - 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() + this.fhirType().equals("decimal") -> { + return this.primitiveValue().toBigDecimal().compareTo(value.primitiveValue().toBigDecimal()) + } + this.fhirType().equals("date") -> { + return clearTimeFromDateValue(this.dateTimeValue().value) + .compareTo(clearTimeFromDateValue(value.dateTimeValue().value)) + } + this.fhirType().equals("dateTime") -> { + return this.dateTimeValue().value.compareTo(value.dateTimeValue().value) + } + this.fhirType().equals("Quantity") -> { + 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() } } return 0 diff --git a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt index 4090eb62a1..ad127d0703 100644 --- a/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt +++ b/datacapture/src/test/java/com/google/android/fhir/datacapture/enablement/EnablementEvaluatorTest.kt @@ -181,6 +181,110 @@ class EnablementEvaluatorTest { .isFalse() } + @Test + fun evaluate_expectAnswerGreaterThanValue_someAnswerGreaterThanValue_shouldReturnTrue() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN, + expected = IntegerType(10), + actual = listOf(IntegerType(20)) + ) + ) + .isTrue() + } + + @Test + fun evaluate_expectAnswerGreaterThanValue_noAnswerGreaterThanValue_shouldReturnFalse() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN, + expected = IntegerType(10), + actual = listOf(IntegerType(5)) + ) + ) + .isFalse() + } + + @Test + fun evaluate_expectAnswerGreaterThanOrEqualToValue_someAnswerGreaterThanOrEqualToValue_shouldReturnTrue() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL, + expected = IntegerType(10), + actual = listOf(IntegerType(10)) + ) + ) + .isTrue() + } + + @Test + fun evaluate_expectAnswerGreaterThanOrEqualToValue_noAnswerGreaterThanOrEqualToValue_shouldReturnFalse() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL, + expected = IntegerType(10), + actual = listOf(IntegerType(5)) + ) + ) + .isFalse() + } + + @Test + fun evaluate_expectAnswerLessThanValue_someAnswerLessThanValue_shouldReturnTrue() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN, + expected = IntegerType(10), + actual = listOf(IntegerType(5)) + ) + ) + .isTrue() + } + + @Test + fun evaluate_expectAnswerLessThanValue_noAnswerLessThanValue_shouldReturnFalse() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN, + expected = IntegerType(10), + actual = listOf(IntegerType(20)) + ) + ) + .isFalse() + } + + @Test + fun evaluate_expectAnswerLessThanOrEqualToValue_someAnswerLessThanOrEqualToValue_shouldReturnTrue() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, + expected = IntegerType(10), + actual = listOf(IntegerType(10)) + ) + ) + .isTrue() + } + + @Test + fun evaluate_expectAnswerLessThanOrEqualToValue_noAnswerLessThanOrEqualToValue_shouldReturnFalse() { + evaluateEnableWhen( + behavior = null, + EnableWhen( + operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, + expected = IntegerType(10), + actual = listOf(IntegerType(20)) + ) + ) + .isFalse() + } + @Test fun evaluate_multipleEnableWhens_behaviorAny_noneSatisfied_shouldReturnFalse() { evaluateEnableWhen( @@ -383,110 +487,6 @@ class EnablementEvaluatorTest { .isFalse() } - @Test - fun evaluate_greaterThan_answersGreaterThanEnableWhenAnswer_shouldReturnTrue() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN, - expected = IntegerType(10), - actual = listOf(IntegerType(20)) - ) - ) - .isTrue() - } - - @Test - fun evaluate_greaterThan_noAnswersGreaterThanEnableWhenAnswer_shouldReturnFalse() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.GREATER_THAN, - expected = IntegerType(10), - actual = listOf(IntegerType(5)) - ) - ) - .isFalse() - } - - @Test - fun evaluate_greaterOrEqual_answersGreaterOrEqualEnableWhenAnswer_shouldReturnTrue() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL, - expected = IntegerType(10), - actual = listOf(IntegerType(10)) - ) - ) - .isTrue() - } - - @Test - fun evaluate_greaterOrEqual_noAnswersGreaterOrEqualEnableWhenAnswer_shouldReturnFalse() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.GREATER_OR_EQUAL, - expected = IntegerType(10), - actual = listOf(IntegerType(5)) - ) - ) - .isFalse() - } - - @Test - fun evaluate_lessThan_answersLessThanEnableWhenAnswer_shouldReturnTrue() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN, - expected = IntegerType(10), - actual = listOf(IntegerType(5)) - ) - ) - .isTrue() - } - - @Test - fun evaluate_lessThan_noAnswersLessThanEnableWhenAnswer_shouldReturnFalse() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.LESS_THAN, - expected = IntegerType(10), - actual = listOf(IntegerType(20)) - ) - ) - .isFalse() - } - - @Test - fun evaluate_lessOrEqual_answerLessOrEqualEnableWhenAnswer_shouldReturnTrue() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, - expected = IntegerType(10), - actual = listOf(IntegerType(10)) - ) - ) - .isTrue() - } - - @Test - fun evaluate_lessOrEqual_noAnswerLessOrEqualEnableWhenAnswer_shouldReturnFalse() { - evaluateEnableWhen( - behavior = null, - EnableWhen( - operator = Questionnaire.QuestionnaireItemOperator.LESS_OR_EQUAL, - expected = IntegerType(10), - actual = listOf(IntegerType(20)) - ) - ) - .isFalse() - } - /** * Evaluates multiple `enableWhen` constraints according to the `behavior` (any or all). * From edeff1de2ac334cbd2e67eb0282a3eceffe4f9f1 Mon Sep 17 00:00:00 2001 From: santosh-pingle Date: Thu, 25 Nov 2021 14:51:02 +0530 Subject: [PATCH 15/15] remove test for null type. --- ...ecimalViewHolderFactoryInstrumentedTest.kt | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextDecimalViewHolderFactoryInstrumentedTest.kt b/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextDecimalViewHolderFactoryInstrumentedTest.kt index 21b217e6ef..e1b9a7bf0c 100644 --- a/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextDecimalViewHolderFactoryInstrumentedTest.kt +++ b/datacapture/src/androidTest/java/com/google/android/fhir/datacapture/views/QuestionnaireItemEditTextDecimalViewHolderFactoryInstrumentedTest.kt @@ -228,31 +228,6 @@ class QuestionnaireItemEditTextDecimalViewHolderFactoryInstrumentedTest { .isEqualTo("Minimum value allowed is:2.1") } - @Test - @UiThreadTest - fun displayValidationResult_noError_shouldShowNoErrorMessage() { - viewHolder.bind( - QuestionnaireItemViewItem( - Questionnaire.QuestionnaireItemComponent().apply { - addExtension().apply { - url = "http://hl7.org/fhir/StructureDefinition/maxValue" - setValue(null) - } - }, - QuestionnaireResponse.QuestionnaireResponseItemComponent().apply { - addAnswer( - QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent().apply { - value = DecimalType("100.3") - } - ) - } - ) {} - ) - - assertThat(viewHolder.itemView.findViewById(R.id.textInputLayout).error) - .isNull() - } - @Test @UiThreadTest fun bind_readOnly_shouldDisableView() {