Skip to content

Commit

Permalink
Merge pull request #5823 from seadowg/xpathprocessor
Browse files Browse the repository at this point in the history
Only load dynamic preload data when needed
  • Loading branch information
grzesiek2010 authored Dec 7, 2023
2 parents 5eac152 + b4f2941 commit 484889e
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package org.odk.collect.android.dynamicpreload

import org.javarosa.core.model.FormDef
import org.javarosa.core.model.QuestionDef
import org.javarosa.core.util.externalizable.ExtUtil
import org.javarosa.core.util.externalizable.Externalizable
import org.javarosa.core.util.externalizable.PrototypeFactory
import org.javarosa.xform.parse.IXFormParserFactory
import org.javarosa.xform.parse.XFormParser
import org.javarosa.xpath.expr.XPathExpression
import java.io.DataInputStream
import java.io.DataOutputStream

Expand All @@ -19,10 +21,36 @@ class DynamicPreloadXFormParserFactory(base: IXFormParserFactory) :
}
}

class DynamicPreloadParseProcessor : XFormParser.FormDefProcessor {
class DynamicPreloadParseProcessor :
XFormParser.XPathProcessor,
XFormParser.QuestionProcessor,
XFormParser.FormDefProcessor {

private var containsPullData = false
private var containsSearch = false

override fun processXPath(xPathExpression: XPathExpression) {
if (containsPullData) {
return // No need to search if we already found pulldata
}

if (xPathExpression.containsFunc("pulldata")) {
containsPullData = true
}
}

override fun processQuestion(question: QuestionDef) {
if (containsSearch) {
return // No need to search if we already found search
}

if (ExternalDataUtil.getSearchXPathExpression(question.appearanceAttr) != null) {
containsSearch = true
}
}

override fun processFormDef(formDef: FormDef) {
formDef.extras.put(DynamicPreloadExtra(true))
formDef.extras.put(DynamicPreloadExtra(containsPullData || containsSearch))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,75 @@ package org.odk.collect.android.dynamicpreload
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.javarosa.core.model.FormDef
import org.javarosa.core.model.QuestionDef
import org.javarosa.xpath.expr.XPathExpression
import org.junit.Test
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock

class DynamicPreloadParseProcessorTest {

private val processor = DynamicPreloadParseProcessor()

/**
* This is currently a "stub" implementation until we have a good way of determining whether
* a form contains search/pulldata.
*/
@Test
fun `usesDynamicPreload is true`() {
fun `usesDynamicPreload is false when xpath does not contain pulldata`() {
val formDef = FormDef()

processor.processXPath(createNonPullDataExpression())
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(false)
)
}

@Test
fun `usesDynamicPreload is true when xpath does contain pulldata`() {
val formDef = FormDef()

processor.processXPath(createPullDataExpression())
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(true)
)
}

@Test
fun `usesDynamicPreload is false when question appearance does not contain search`() {
val formDef = FormDef()

processor.processQuestion(createQuestion(appearance = "minimal"))
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(false)
)
}

@Test
fun `usesDynamicPreload is true when question appearance does contain search`() {
val formDef = FormDef()

processor.processQuestion(createQuestion(appearance = "search('fruits')"))
processor.processFormDef(formDef)
assertThat(
formDef.extras.get(DynamicPreloadExtra::class.java).usesDynamicPreload,
equalTo(true)
)
}

private fun createNonPullDataExpression() = mock<XPathExpression> {
on { containsFunc("pulldata") } doReturn false
}

private fun createPullDataExpression() = mock<XPathExpression> {
on { containsFunc("pulldata") } doReturn true
}

private fun createQuestion(appearance: String): QuestionDef {
return mock() {
on { appearanceAttr } doReturn appearance
}
}
}

0 comments on commit 484889e

Please sign in to comment.