mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
Added compose integration tests
commit_hash:b8423b44ec162dc4882e3be7cf8fc61fab2acbb3
This commit is contained in:
@@ -4,8 +4,8 @@ import android.content.ContextWrapper
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.yandex.div.compose.dagger.DivContextComponent
|
||||
import com.yandex.div.compose.internal.DivDebugFeatures
|
||||
import com.yandex.div.compose.views.DivLocalContext
|
||||
import com.yandex.div.compose.internal.DivActionPerformer
|
||||
import com.yandex.div.core.annotations.InternalApi
|
||||
import com.yandex.div.core.annotations.PublicApi
|
||||
import com.yandex.div.core.expression.variables.DivVariableController
|
||||
@@ -20,8 +20,8 @@ class DivContext @Inject @MainThread internal constructor(
|
||||
|
||||
@InternalApi
|
||||
@VisibleForTesting
|
||||
val actionPerformer: DivActionPerformer
|
||||
get() = component.actionPerformer
|
||||
val debugFeatures: DivDebugFeatures
|
||||
get() = component.debugFeatures
|
||||
|
||||
internal fun createLocalContext(
|
||||
variableController: DivVariableController,
|
||||
@@ -42,8 +42,6 @@ class DivContext @Inject @MainThread internal constructor(
|
||||
localComponent.triggerStorage.add(it)
|
||||
}
|
||||
|
||||
val context = localComponent.context
|
||||
actionPerformer.actionHandlingContext = context.actionHandlingContext
|
||||
return context
|
||||
return localComponent.context
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ import com.yandex.div.compose.DivComposeConfiguration
|
||||
import com.yandex.div.compose.DivReporter
|
||||
import com.yandex.div.compose.actions.DivActionHandler
|
||||
import com.yandex.div.core.expression.variables.DivVariableController
|
||||
import com.yandex.div.compose.internal.DivActionPerformer
|
||||
import com.yandex.div.compose.internal.DivDebugFeatures
|
||||
import com.yandex.yatagan.BindsInstance
|
||||
import com.yandex.yatagan.Component
|
||||
import javax.inject.Named
|
||||
@@ -21,10 +21,10 @@ import javax.inject.Named
|
||||
internal interface DivContextComponent {
|
||||
|
||||
val actionHandler: DivActionHandler
|
||||
val actionPerformer: DivActionPerformer
|
||||
val baseContext: Context
|
||||
val reporter: DivReporter
|
||||
val debugFeatures: DivDebugFeatures
|
||||
val imageLoader: ImageLoader
|
||||
val reporter: DivReporter
|
||||
|
||||
@get:Named(Names.HOST_VARIABLES)
|
||||
val variableController: DivVariableController
|
||||
|
||||
+4
-1
@@ -15,6 +15,7 @@ import com.yandex.div.evaluable.function.GeneratedBuiltinFunctionProvider
|
||||
import com.yandex.div.internal.parser.Converter
|
||||
import com.yandex.div.internal.parser.TypeHelper
|
||||
import com.yandex.div.internal.parser.ValueValidator
|
||||
import com.yandex.div.internal.variables.variableValueToEvaluableValue
|
||||
import com.yandex.div.json.ParsingErrorLogger
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div.json.invalidValue
|
||||
@@ -37,7 +38,9 @@ internal class DivComposeExpressionResolver @Inject constructor(
|
||||
|
||||
init {
|
||||
val evaluationContext = EvaluationContext(
|
||||
variableProvider = { name -> variableController.get(name)?.getValue() },
|
||||
variableProvider = { name ->
|
||||
variableController.get(name)?.getValue().variableValueToEvaluableValue()
|
||||
},
|
||||
storedValueProvider = { _ -> null },
|
||||
functionProvider = GeneratedBuiltinFunctionProvider,
|
||||
warningSender = EvaluatorWarningSender(reporter)
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package com.yandex.div.compose.internal
|
||||
|
||||
import com.yandex.div.compose.actions.DivActionHandler
|
||||
import com.yandex.div.compose.actions.DivActionHandlingContext
|
||||
import com.yandex.div.compose.dagger.DivContextScope
|
||||
import com.yandex.div.core.annotations.InternalApi
|
||||
import com.yandex.div2.DivAction
|
||||
import javax.inject.Inject
|
||||
|
||||
@DivContextScope
|
||||
@InternalApi
|
||||
class DivActionPerformer @Inject internal constructor(
|
||||
private val actionHandler: DivActionHandler
|
||||
) {
|
||||
internal var actionHandlingContext: DivActionHandlingContext? = null
|
||||
|
||||
fun perform(action: DivAction) {
|
||||
actionHandlingContext?.let {
|
||||
actionHandler.handle(context = it, action = action)
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.yandex.div.compose.internal
|
||||
|
||||
import com.yandex.div.compose.actions.DivActionHandler
|
||||
import com.yandex.div.compose.dagger.DivContextScope
|
||||
import com.yandex.div.compose.views.DivLocalContext
|
||||
import com.yandex.div.core.annotations.InternalApi
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div2.DivAction
|
||||
import javax.inject.Inject
|
||||
|
||||
@DivContextScope
|
||||
@InternalApi
|
||||
class DivDebugFeatures @Inject internal constructor(
|
||||
private val actionHandler: DivActionHandler
|
||||
) {
|
||||
internal var lastViewLocalContext: DivLocalContext? = null
|
||||
|
||||
val expressionResolver: ExpressionResolver?
|
||||
get() = lastViewLocalContext?.expressionResolver
|
||||
|
||||
fun performAction(action: DivAction) {
|
||||
lastViewLocalContext?.let {
|
||||
actionHandler.handle(context = it.actionHandlingContext, action = action)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -33,7 +33,9 @@ internal fun WithLocalDivContext(data: DivData, content: @Composable () -> Unit)
|
||||
variableController = DivVariableController(divContext.component.variableController),
|
||||
triggers = data.variableTriggers.orEmpty(),
|
||||
variables = data.variables.orEmpty()
|
||||
)
|
||||
).also {
|
||||
divContext.debugFeatures.lastViewLocalContext = it
|
||||
}
|
||||
}
|
||||
CompositionLocalProvider(LocalDivContext provides localContext, content)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.yandex.div.compose
|
||||
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.test.core.app.ApplicationProvider.getApplicationContext
|
||||
import com.yandex.div.core.expression.variables.DivVariableController
|
||||
import com.yandex.div.test.crossplatform.IntegrationTestCase
|
||||
import com.yandex.div.test.crossplatform.IntegrationTestCaseParser
|
||||
import com.yandex.div.test.crossplatform.ParsingResult
|
||||
import com.yandex.div.test.crossplatform.ParsingUtils
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.ParameterizedRobolectricTestRunner
|
||||
|
||||
@RunWith(ParameterizedRobolectricTestRunner::class)
|
||||
class IntegrationTest(testCaseParsingResult: ParsingResult<IntegrationTestCase>) {
|
||||
|
||||
private val testCase = testCaseParsingResult.getOrThrow()
|
||||
|
||||
@get:Rule
|
||||
val rule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun run() {
|
||||
val divData = testCase.parseDivData() ?: return
|
||||
|
||||
val variableController = DivVariableController()
|
||||
val divContext = DivComposeConfiguration(
|
||||
reporter = TestReporter(),
|
||||
variableController = variableController
|
||||
).createContext(baseContext = getApplicationContext())
|
||||
|
||||
testCase.declareResultVariables(
|
||||
variables = divData.variables ?: emptyList(),
|
||||
variableController = variableController
|
||||
)
|
||||
|
||||
rule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides divContext) {
|
||||
DivView(data = divData)
|
||||
}
|
||||
}
|
||||
|
||||
testCase.parseActions().forEach {
|
||||
divContext.debugFeatures.performAction(it)
|
||||
}
|
||||
|
||||
testCase.checkResult(
|
||||
expressionResolver = divContext.debugFeatures.expressionResolver!!
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Store parsed test cases to prevent multiple parsing by
|
||||
// ParameterizedRobolectricTestRunner
|
||||
private val cases: List<ParsingResult<IntegrationTestCase>> = run {
|
||||
ParsingUtils.parseFiles("integration_test_data") { file, json ->
|
||||
if (ignoredFiles.contains(file.name)) {
|
||||
emptyList()
|
||||
} else {
|
||||
IntegrationTestCaseParser.parseCases(file.name, json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Suppress("unused")
|
||||
@ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
|
||||
fun cases() = cases
|
||||
}
|
||||
}
|
||||
|
||||
private val ignoredFiles = listOf(
|
||||
"array_variable_mutation.json",
|
||||
"decl_expressions_item_builder.json",
|
||||
"decl_expressions_item_builder_override.json",
|
||||
"dict_set_value.json",
|
||||
"expression_with_several_local_functions.json",
|
||||
"item_builder_variable_triggers.json",
|
||||
"local_functions_array.json",
|
||||
"local_functions_datetime.json",
|
||||
"local_functions_color.json",
|
||||
"local_functions_dict.json",
|
||||
"local_functions_div_data.json",
|
||||
"local_functions_int.json",
|
||||
"local_functions_number.json",
|
||||
"local_functions_string.json",
|
||||
"local_functions_url.json",
|
||||
"local-triggers-gallery.json",
|
||||
"local-triggers-gallery-with-item-builder.json",
|
||||
"local-triggers-states.json",
|
||||
"local-triggers-tabs.json",
|
||||
"properties_cycled.json",
|
||||
"property_boolean_value_from_dict.json",
|
||||
"property_color_value_from_array.json",
|
||||
"property_color_value_from_dict.json",
|
||||
"property_cycle.json",
|
||||
"property_integer_value_from_dict.json",
|
||||
"property_new_value_variable_name.json",
|
||||
"property_number_value_from_dict.json",
|
||||
"property_string_value_and_variable_from_dict.json",
|
||||
"property_string_value_from_dict.json",
|
||||
"property_string_value_from_variable.json",
|
||||
"property_url_value_from_dict.json",
|
||||
"property_without_setter.json",
|
||||
"update_structure.json",
|
||||
"wrap_content_constraints_warning.json",
|
||||
)
|
||||
Reference in New Issue
Block a user