mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
Support expressions in variables initialization
commit_hash:1af4f28b41a00effe9c777281d3937e9e9581676
This commit is contained in:
@@ -5,6 +5,7 @@ package com.yandex.div
|
||||
|
||||
import android.net.Uri
|
||||
import androidx.annotation.ColorInt
|
||||
import com.yandex.div.json.expressions.Expression
|
||||
import com.yandex.div2.ArrayVariable
|
||||
import com.yandex.div2.BoolVariable
|
||||
import com.yandex.div2.ColorVariable
|
||||
@@ -18,33 +19,33 @@ import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
fun integerVariable(name: String, value: Long): DivVariable.Integer {
|
||||
return DivVariable.Integer(IntegerVariable(name, value))
|
||||
return DivVariable.Integer(IntegerVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
fun numberVariable(name: String, value: Double): DivVariable.Number {
|
||||
return DivVariable.Number(NumberVariable(name, value))
|
||||
return DivVariable.Number(NumberVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
fun boolVariable(name: String, value: Boolean): DivVariable.Bool {
|
||||
return DivVariable.Bool(BoolVariable(name, value))
|
||||
return DivVariable.Bool(BoolVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
fun stringVariable(name: String, value: String): DivVariable.Str {
|
||||
return DivVariable.Str(StrVariable(name, value))
|
||||
return DivVariable.Str(StrVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
fun colorVariable(name: String, @ColorInt value: Int): DivVariable.Color {
|
||||
return DivVariable.Color(ColorVariable(name, value))
|
||||
return DivVariable.Color(ColorVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
fun urlVariable(name: String, value: Uri): DivVariable.Url {
|
||||
return DivVariable.Url(UrlVariable(name, value))
|
||||
return DivVariable.Url(UrlVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
internal fun dictVariable(name: String, value: JSONObject): DivVariable.Dict {
|
||||
return DivVariable.Dict(DictVariable(name, value))
|
||||
return DivVariable.Dict(DictVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
internal fun arrayVariable(name: String, value: JSONArray): DivVariable.Array {
|
||||
return DivVariable.Array(ArrayVariable(name, value))
|
||||
return DivVariable.Array(ArrayVariable(name, Expression.constant(value)))
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.yandex.div.internal.Assert
|
||||
import com.yandex.div.internal.parser.STRING_TO_COLOR_INT
|
||||
import com.yandex.div.internal.util.toBoolean
|
||||
import com.yandex.div.json.JSONSerializable
|
||||
import com.yandex.div.json.expressions.Expression
|
||||
import com.yandex.div2.BoolVariable
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
@@ -321,14 +322,14 @@ sealed class Variable {
|
||||
|
||||
fun writeToJSON(): JSONObject {
|
||||
val serializable: JSONSerializable = when (this) {
|
||||
is ArrayVariable -> com.yandex.div2.ArrayVariable(this.name, this.value)
|
||||
is BooleanVariable -> BoolVariable(this.name, this.value)
|
||||
is ColorVariable -> com.yandex.div2.ColorVariable(this.name, this.value.value)
|
||||
is DictVariable -> com.yandex.div2.DictVariable(this.name, this.value)
|
||||
is DoubleVariable -> com.yandex.div2.NumberVariable(this.name, this.value)
|
||||
is IntegerVariable -> com.yandex.div2.IntegerVariable(this.name, this.value)
|
||||
is StringVariable -> com.yandex.div2.StrVariable(this.name, this.value)
|
||||
is UrlVariable -> com.yandex.div2.UrlVariable(this.name, this.value)
|
||||
is ArrayVariable -> com.yandex.div2.ArrayVariable(this.name, Expression.constant(this.value))
|
||||
is BooleanVariable -> BoolVariable(this.name, Expression.constant(this.value))
|
||||
is ColorVariable -> com.yandex.div2.ColorVariable(this.name, Expression.constant(this.value.value))
|
||||
is DictVariable -> com.yandex.div2.DictVariable(this.name, Expression.constant(this.value))
|
||||
is DoubleVariable -> com.yandex.div2.NumberVariable(this.name, Expression.constant(this.value))
|
||||
is IntegerVariable -> com.yandex.div2.IntegerVariable(this.name, Expression.constant(this.value))
|
||||
is StringVariable -> com.yandex.div2.StrVariable(this.name, Expression.constant(this.value))
|
||||
is UrlVariable -> com.yandex.div2.UrlVariable(this.name, Expression.constant(this.value))
|
||||
}
|
||||
|
||||
return serializable.writeToJSON()
|
||||
|
||||
+14
-13
@@ -20,6 +20,7 @@ import com.yandex.div.data.VariableDeclarationException
|
||||
import com.yandex.div.evaluable.EvaluationContext
|
||||
import com.yandex.div.evaluable.Evaluator
|
||||
import com.yandex.div.evaluable.function.GeneratedBuiltinFunctionProvider
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div2.DivData
|
||||
import com.yandex.div2.DivVariable
|
||||
import java.util.Collections
|
||||
@@ -45,7 +46,7 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
val result = runtimes.getOrPut(tag.id) { createRuntimeFor(data, tag) }
|
||||
val errorCollector = errorCollectors.getOrCreate(tag, data)
|
||||
divDataTags.getOrPut(div2View, ::mutableSetOf).add(tag.id)
|
||||
ensureVariablesSynced(result.variableController, data, errorCollector)
|
||||
ensureVariablesSynced(result.variableController, result.expressionResolver, data, errorCollector)
|
||||
result.triggersController?.ensureTriggersSynced(data.variableTriggers ?: emptyList())
|
||||
return result
|
||||
}
|
||||
@@ -69,13 +70,14 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
|
||||
private fun ensureVariablesSynced(
|
||||
v: VariableController,
|
||||
resolver: ExpressionResolver,
|
||||
data: DivData,
|
||||
errorCollector: ErrorCollector
|
||||
) {
|
||||
data.variables?.forEach {
|
||||
val existingVariable = v.getMutableVariable(it.name) ?: run {
|
||||
try {
|
||||
v.declare(it.toVariable())
|
||||
v.declare(it.toVariable(resolver))
|
||||
} catch (e: VariableDeclarationException) {
|
||||
errorCollector.logError(e)
|
||||
}
|
||||
@@ -110,17 +112,8 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
|
||||
private fun createRuntimeFor(data: DivData, tag: DivDataTag): ExpressionsRuntime {
|
||||
val errorCollector = errorCollectors.getOrCreate(tag, data)
|
||||
val variableController = VariableControllerImpl().apply {
|
||||
data.variables?.forEach { divVariable: DivVariable ->
|
||||
try {
|
||||
declare(divVariable.toVariable())
|
||||
} catch (e: VariableDeclarationException) {
|
||||
errorCollector.logError(e)
|
||||
}
|
||||
}
|
||||
|
||||
addSource(divVariableController.variableSource)
|
||||
}
|
||||
val variableController = VariableControllerImpl()
|
||||
variableController.addSource(divVariableController.variableSource)
|
||||
|
||||
val functionProvider = FunctionProviderDecorator(GeneratedBuiltinFunctionProvider)
|
||||
val evaluationContext = EvaluationContext(
|
||||
@@ -155,6 +148,14 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
|
||||
onCreateCallback = callback,
|
||||
)
|
||||
|
||||
data.variables?.forEach { divVariable: DivVariable ->
|
||||
try {
|
||||
variableController.declare(divVariable.toVariable(expressionResolver))
|
||||
} catch (e: VariableDeclarationException) {
|
||||
errorCollector.logError(e)
|
||||
}
|
||||
}
|
||||
|
||||
val triggersController = TriggersController(
|
||||
variableController,
|
||||
expressionResolver,
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ internal class DivRuntimeVisitor @Inject constructor(
|
||||
div: Div,
|
||||
divView: Div2View,
|
||||
path: String,
|
||||
parentRuntime: ExpressionsRuntime?
|
||||
parentRuntime: ExpressionsRuntime
|
||||
): ExpressionsRuntime? {
|
||||
if (!div.needLocalRuntime) return parentRuntime
|
||||
|
||||
|
||||
+50
-54
@@ -6,20 +6,18 @@ import com.yandex.div.core.ObserverList
|
||||
import com.yandex.div.core.expression.ExpressionResolverImpl
|
||||
import com.yandex.div.core.expression.ExpressionsRuntime
|
||||
import com.yandex.div.core.expression.triggers.TriggersController
|
||||
import com.yandex.div.core.expression.variables.VariableController
|
||||
import com.yandex.div.core.expression.variables.VariableControllerImpl
|
||||
import com.yandex.div.core.expression.variables.toVariable
|
||||
import com.yandex.div.core.util.toLocalFunctions
|
||||
import com.yandex.div.core.util.toVariables
|
||||
import com.yandex.div.core.view2.Div2View
|
||||
import com.yandex.div.core.view2.divs.DivActionBinder
|
||||
import com.yandex.div.core.view2.errors.ErrorCollector
|
||||
import com.yandex.div.data.Variable
|
||||
import com.yandex.div.evaluable.EvaluationContext
|
||||
import com.yandex.div.evaluable.Evaluator
|
||||
import com.yandex.div.internal.Assert
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div2.Div
|
||||
import com.yandex.div2.DivBase
|
||||
import com.yandex.div2.DivFunction
|
||||
import com.yandex.div2.DivTrigger
|
||||
|
||||
private const val ERROR_UNKNOWN_RESOLVER =
|
||||
@@ -67,18 +65,33 @@ internal class RuntimeStore(
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns runtime if it have been store before, otherwise creates new runtime using
|
||||
* @param parentRuntime or @param parentResolver.
|
||||
*
|
||||
* NOTE: Always provide parentResolver or parentRuntime.
|
||||
* Otherwise, if runtime wasn't created it will be created using rootRuntime
|
||||
* Returns runtime if it have been stored before, otherwise creates new runtime using
|
||||
* @param parentResolver
|
||||
*/
|
||||
internal fun getOrCreateRuntime(
|
||||
path: String,
|
||||
div: Div,
|
||||
parentResolver: ExpressionResolver? = null,
|
||||
parentRuntime: ExpressionsRuntime? = null,
|
||||
) = tree.getNode(path)?.runtime ?: getRuntimeOrCreateChild(path, div, null, parentResolver, parentRuntime)
|
||||
parentResolver: ExpressionResolver,
|
||||
): ExpressionsRuntime? {
|
||||
path.runtime?.let { return it }
|
||||
|
||||
val parentRuntime = getRuntimeWithOrNull(parentResolver)
|
||||
val runtime = parentRuntime ?: rootRuntime ?: run {
|
||||
reportError(ERROR_ROOT_RUNTIME_NOT_SPECIFIED)
|
||||
return null
|
||||
}
|
||||
|
||||
return getRuntimeOrCreateChild(path, div, runtime, parentRuntime)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns runtime if it have been stored before, otherwise creates new runtime using
|
||||
* @param parentRuntime
|
||||
*/
|
||||
internal fun getOrCreateRuntime(path: String, div: Div, parentRuntime: ExpressionsRuntime) =
|
||||
path.runtime ?: getRuntimeOrCreateChild(path, div, parentRuntime, parentRuntime)
|
||||
|
||||
private val String.runtime get() = tree.getNode(this)?.runtime
|
||||
|
||||
internal fun getRuntimeWithOrNull(resolver: ExpressionResolver) = resolverToRuntime[resolver]
|
||||
|
||||
@@ -103,7 +116,7 @@ internal class RuntimeStore(
|
||||
path: String,
|
||||
div: Div?,
|
||||
resolver: ExpressionResolver,
|
||||
parentResolver: ExpressionResolver?,
|
||||
parentResolver: ExpressionResolver,
|
||||
): ExpressionsRuntime? {
|
||||
val runtimeForPath = tree.getNode(path)?.runtime
|
||||
if (resolver == runtimeForPath?.expressionResolver) return runtimeForPath
|
||||
@@ -114,7 +127,7 @@ internal class RuntimeStore(
|
||||
}
|
||||
|
||||
runtimeForPath?.let { tree.removeRuntimeAndCleanup(divView, it, path) }
|
||||
return getRuntimeOrCreateChild(path, div, existingRuntime, parentResolver)
|
||||
return getRuntimeOrCreateChild(path, div, existingRuntime, getRuntimeWithOrNull(parentResolver))
|
||||
}
|
||||
|
||||
internal fun cleanup(divView: DivViewFacade) {
|
||||
@@ -137,15 +150,11 @@ internal class RuntimeStore(
|
||||
baseRuntime: ExpressionsRuntime,
|
||||
parentRuntime: ExpressionsRuntime?,
|
||||
path: String,
|
||||
variables: List<Variable>?,
|
||||
variablesTriggers: List<DivTrigger>?,
|
||||
functions: List<DivFunction>?,
|
||||
div: DivBase,
|
||||
): ExpressionsRuntime {
|
||||
val localVariableController = VariableControllerImpl(baseRuntime.variableController)
|
||||
if (!variables.isNullOrEmpty()) {
|
||||
variables.forEach { localVariableController.declare(it) }
|
||||
}
|
||||
|
||||
val functions = div.functions
|
||||
var functionProvider = baseRuntime.functionProvider
|
||||
if (!functions.isNullOrEmpty()) {
|
||||
functionProvider += functions.toLocalFunctions()
|
||||
@@ -168,50 +177,37 @@ internal class RuntimeStore(
|
||||
onCreateCallback = onCreateCallback,
|
||||
)
|
||||
|
||||
val triggerController = if (variablesTriggers.isNullOrEmpty()) {
|
||||
null
|
||||
} else {
|
||||
TriggersController(
|
||||
localVariableController,
|
||||
resolver,
|
||||
evaluator,
|
||||
errorCollector,
|
||||
div2Logger,
|
||||
divActionBinder
|
||||
).apply {
|
||||
ensureTriggersSynced(variablesTriggers)
|
||||
}
|
||||
div.variables?.forEach {
|
||||
localVariableController.declare(it.toVariable(resolver))
|
||||
}
|
||||
|
||||
val triggerController = div.variableTriggers.toTriggersController(localVariableController, resolver, evaluator)
|
||||
|
||||
return ExpressionsRuntime(resolver, localVariableController, triggerController, functionProvider, this).also {
|
||||
putRuntime(it, path, parentRuntime)
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<DivTrigger>?.toTriggersController(
|
||||
variableController: VariableController,
|
||||
resolver: ExpressionResolver,
|
||||
evaluator: Evaluator,
|
||||
): TriggersController? {
|
||||
if (isNullOrEmpty()) return null
|
||||
val controller =
|
||||
TriggersController(variableController, resolver, evaluator, errorCollector, div2Logger, divActionBinder)
|
||||
controller.ensureTriggersSynced(this)
|
||||
return controller
|
||||
}
|
||||
|
||||
private fun getRuntimeOrCreateChild(
|
||||
path: String,
|
||||
div: Div?,
|
||||
existingRuntime: ExpressionsRuntime? = null,
|
||||
parentResolver: ExpressionResolver? = null,
|
||||
parentRuntime: ExpressionsRuntime? = null,
|
||||
): ExpressionsRuntime? {
|
||||
val runtime = existingRuntime
|
||||
?: parentRuntime
|
||||
?: parentResolver?.let { getRuntimeWithOrNull(it) }
|
||||
?: rootRuntime
|
||||
?: run {
|
||||
reportError(ERROR_ROOT_RUNTIME_NOT_SPECIFIED)
|
||||
return null
|
||||
}
|
||||
|
||||
val parentRuntime = parentRuntime ?: parentResolver?.let { getRuntimeWithOrNull(it) }
|
||||
|
||||
val variables = div?.value()?.variables?.toVariables()
|
||||
val variableTriggers = div?.value()?.variableTriggers
|
||||
val functions = div?.value()?.functions
|
||||
|
||||
if (needLocalRuntime(variables, variableTriggers, functions)) {
|
||||
return createChildRuntime(runtime, parentRuntime, path, variables, variableTriggers, functions)
|
||||
runtime: ExpressionsRuntime,
|
||||
parentRuntime: ExpressionsRuntime?,
|
||||
): ExpressionsRuntime {
|
||||
if (div != null && div.needLocalRuntime) {
|
||||
return createChildRuntime(runtime, parentRuntime, path, div.value())
|
||||
}
|
||||
|
||||
tree.storeRuntime(runtime, parentRuntime, path)
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
package com.yandex.div.core.expression.local
|
||||
|
||||
import com.yandex.div.data.Variable
|
||||
import com.yandex.div2.Div
|
||||
import com.yandex.div2.DivFunction
|
||||
import com.yandex.div2.DivTrigger
|
||||
|
||||
internal val Div.needLocalRuntime get() =
|
||||
!value().run { variables.isNullOrEmpty() && variableTriggers.isNullOrEmpty() && functions.isNullOrEmpty() }
|
||||
|
||||
internal fun needLocalRuntime(
|
||||
variables: List<Variable>?,
|
||||
variableTriggers: List<DivTrigger>?,
|
||||
functions: List<DivFunction>?
|
||||
) = !(variables.isNullOrEmpty() && variableTriggers.isNullOrEmpty() && functions.isNullOrEmpty())
|
||||
|
||||
+19
-11
@@ -6,6 +6,7 @@ import com.yandex.div.data.Variable
|
||||
import com.yandex.div.internal.parser.JsonParser
|
||||
import com.yandex.div.json.ParsingErrorLogger
|
||||
import com.yandex.div.json.ParsingException
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div2.DivVariable
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
@@ -16,7 +17,14 @@ object DivVariablesParser {
|
||||
* @param variablesArray json-array of variables for parsing.
|
||||
*/
|
||||
@Throws(ParsingException::class)
|
||||
fun parse(variablesArray: JSONArray, logger: ParsingErrorLogger): List<Variable> {
|
||||
fun parse(variablesArray: JSONArray, logger: ParsingErrorLogger) =
|
||||
parse(variablesArray, ExpressionResolver.EMPTY, logger)
|
||||
|
||||
/**
|
||||
* @param variablesArray json-array of variables for parsing.
|
||||
*/
|
||||
@Throws(ParsingException::class)
|
||||
fun parse(variablesArray: JSONArray, resolver: ExpressionResolver, logger: ParsingErrorLogger): List<Variable> {
|
||||
val env = DivParsingEnvironment(logger)
|
||||
val listValidator: (value: List<DivVariable>) -> Boolean = { true }
|
||||
val key = "variables"
|
||||
@@ -25,49 +33,49 @@ object DivVariablesParser {
|
||||
}
|
||||
val divVariables: List<DivVariable> = JsonParser.readList(
|
||||
jsonObject, key, DivVariable.CREATOR, listValidator, logger, env)
|
||||
return divVariables.map { it.toVariable() }
|
||||
return divVariables.map { it.toVariable(resolver) }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun DivVariable.toVariable(): Variable {
|
||||
internal fun DivVariable.toVariable(resolver: ExpressionResolver): Variable {
|
||||
return when (this) {
|
||||
is DivVariable.Bool -> {
|
||||
Variable.BooleanVariable(
|
||||
this.value.name, this.value.value)
|
||||
this.value.name, this.value.value.evaluate(resolver))
|
||||
}
|
||||
is DivVariable.Integer -> {
|
||||
Variable.IntegerVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
is DivVariable.Number -> {
|
||||
Variable.DoubleVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
is DivVariable.Str -> {
|
||||
Variable.StringVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
is DivVariable.Color -> {
|
||||
Variable.ColorVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
is DivVariable.Url -> {
|
||||
Variable.UrlVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
is DivVariable.Dict -> {
|
||||
Variable.DictVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
is DivVariable.Array -> {
|
||||
Variable.ArrayVariable(
|
||||
this.value.name, this.value.value
|
||||
this.value.name, this.value.value.evaluate(resolver)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
package com.yandex.div.core.util
|
||||
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.Interpolator
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.core.view.children
|
||||
import com.yandex.div.core.animation.EaseInInterpolator
|
||||
import com.yandex.div.core.animation.EaseInOutInterpolator
|
||||
import com.yandex.div.core.animation.EaseInterpolator
|
||||
import com.yandex.div.core.animation.EaseOutInterpolator
|
||||
import com.yandex.div.core.animation.SpringInterpolator
|
||||
import com.yandex.div.core.animation.reversed
|
||||
import com.yandex.div.core.expression.variables.toVariable
|
||||
import com.yandex.div.core.view2.divs.dpToPx
|
||||
import com.yandex.div.data.Variable
|
||||
import com.yandex.div.internal.core.buildItems
|
||||
import com.yandex.div.internal.core.nonNullItems
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
@@ -38,7 +33,6 @@ import com.yandex.div2.DivState
|
||||
import com.yandex.div2.DivSwitch
|
||||
import com.yandex.div2.DivTabs
|
||||
import com.yandex.div2.DivText
|
||||
import com.yandex.div2.DivVariable
|
||||
import com.yandex.div2.DivVideo
|
||||
import java.util.Collections.min
|
||||
|
||||
@@ -113,13 +107,6 @@ internal val DivAnimationDirection.isAlternated: Boolean
|
||||
}
|
||||
}
|
||||
|
||||
internal fun requestHierarchyLayout(v : View) {
|
||||
v.requestLayout()
|
||||
if (v is ViewGroup) {
|
||||
v.children.forEach { requestHierarchyLayout(it) }
|
||||
}
|
||||
}
|
||||
|
||||
internal fun DivBorder.getCornerRadii(
|
||||
widthPx: Float,
|
||||
heightPx: Float,
|
||||
@@ -211,9 +198,3 @@ internal val Div.isBranch: Boolean
|
||||
|
||||
internal val Div.isLeaf: Boolean
|
||||
get() = !isBranch
|
||||
|
||||
internal fun List<DivVariable>.toVariables(): List<Variable> {
|
||||
return map {
|
||||
it.toVariable()
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -13,6 +13,8 @@ import com.yandex.div.data.Variable
|
||||
import com.yandex.div.evaluable.EvaluationContext
|
||||
import com.yandex.div.evaluable.Evaluator
|
||||
import com.yandex.div.internal.Assert
|
||||
import com.yandex.div.json.expressions.Expression
|
||||
import com.yandex.div.json.expressions.ExpressionResolver
|
||||
import com.yandex.div2.Div
|
||||
import com.yandex.div2.DivBase
|
||||
import com.yandex.div2.DivVariable
|
||||
@@ -82,7 +84,7 @@ class RuntimeStoreTest {
|
||||
Assert.assertNotNull(underTest.getRuntimeWithOrNull(newResolver))
|
||||
Assert.assertEquals(
|
||||
runtimeFromCallback,
|
||||
underTest.getOrCreateRuntime(path.fullPath, div)
|
||||
underTest.getOrCreateRuntime(path.fullPath, div, newResolver)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -91,7 +93,7 @@ class RuntimeStoreTest {
|
||||
setVariable()
|
||||
underTest.resolveRuntimeWith(divView, path.fullPath, div, resolver, resolver)
|
||||
|
||||
val runtime = underTest.getOrCreateRuntime(path.fullPath, div)
|
||||
val runtime = underTest.getOrCreateRuntime(path.fullPath, div, resolver)
|
||||
Assert.assertNotNull(underTest.getRuntimeWithOrNull(resolver))
|
||||
Assert.assertNotNull(runtime)
|
||||
Assert.assertEquals(
|
||||
@@ -105,7 +107,7 @@ class RuntimeStoreTest {
|
||||
val runtime = ExpressionsRuntime(resolver, mock(), null, functionProvider, underTest)
|
||||
underTest.putRuntime(runtime, PATH, rootRuntime)
|
||||
|
||||
Assert.assertEquals(runtime, underTest.getOrCreateRuntime(path.fullPath, div))
|
||||
Assert.assertEquals(runtime, underTest.getOrCreateRuntime(path.fullPath, div, resolver))
|
||||
Assert.assertNotSame(runtime, rootRuntime)
|
||||
Assert.assertNotNull(underTest.getRuntimeWithOrNull(resolver))
|
||||
}
|
||||
@@ -148,7 +150,7 @@ class RuntimeStoreTest {
|
||||
|
||||
@Test
|
||||
fun `getOrCreateRuntime returns root runtime if parent runtime is not found`() {
|
||||
val runtime = underTest.getOrCreateRuntime(path.fullPath, div)
|
||||
val runtime = underTest.getOrCreateRuntime(path.fullPath, div, mock<ExpressionResolver>())
|
||||
Assert.assertEquals(rootRuntime, runtime)
|
||||
Assert.assertNotNull(underTest.getRuntimeWithOrNull(resolver))
|
||||
}
|
||||
@@ -165,7 +167,7 @@ class RuntimeStoreTest {
|
||||
)
|
||||
Assert.assertEquals(
|
||||
runtimeFromCallback,
|
||||
underTest.getOrCreateRuntime(path.fullPath, div)
|
||||
underTest.getOrCreateRuntime(path.fullPath, div, resolver)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -180,7 +182,7 @@ class RuntimeStoreTest {
|
||||
)
|
||||
|
||||
underTest.resolveRuntimeWith(divView, path.fullPath, div, resolver, resolver)
|
||||
val newRuntime = underTest.getOrCreateRuntime(path.fullPath, div)
|
||||
val newRuntime = underTest.getOrCreateRuntime(path.fullPath, div, resolver)
|
||||
|
||||
Assert.assertNotNull(newRuntime)
|
||||
Assert.assertEquals(
|
||||
@@ -194,7 +196,7 @@ class RuntimeStoreTest {
|
||||
}
|
||||
|
||||
private fun setVariable() {
|
||||
val variables = listOf(DivVariable.Integer(IntegerVariable(CHILD_VARIABLE, 123)))
|
||||
val variables = listOf(DivVariable.Integer(IntegerVariable(CHILD_VARIABLE, Expression.constant(123))))
|
||||
whenever(divBase.variables).doReturn(variables)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -125,8 +125,8 @@ class LocalVariablesTest {
|
||||
}
|
||||
|
||||
private fun setVariable(name: String, value: String, path: String) {
|
||||
val variableController = div2View.expressionsRuntime
|
||||
?.runtimeStore?.getOrCreateRuntime(path, div)?.variableController
|
||||
val runtime = div2View.expressionsRuntime
|
||||
val variableController = runtime?.runtimeStore?.getOrCreateRuntime(path, div, runtime)?.variableController
|
||||
val variable = variableController?.getMutableVariable(name) ?: return
|
||||
variable.set(value)
|
||||
}
|
||||
|
||||
+3
-2
@@ -9,6 +9,7 @@ import com.yandex.div.core.expression.ExpressionTestCaseUtils
|
||||
import com.yandex.div.core.expression.ExpressionTestCaseUtils.VALUE_TYPE_ARRAY
|
||||
import com.yandex.div.core.expression.ExpressionTestCaseUtils.VALUE_TYPE_DICT
|
||||
import com.yandex.div.core.expression.ExpressionTestCaseUtils.createVariable
|
||||
import com.yandex.div.core.expression.variables.wrapVariableValue
|
||||
import com.yandex.div.core.images.DivImageDownloadCallback
|
||||
import com.yandex.div.core.images.DivImageLoader
|
||||
import com.yandex.div.core.images.LoadReference
|
||||
@@ -56,8 +57,8 @@ class IntegrationMultiplatformTest(testCase: TestCaseOrError<IntegrationTestCase
|
||||
)
|
||||
}
|
||||
is IntegrationTestCase.ExpectedResult.Variable -> {
|
||||
val expectedValue = it.value
|
||||
val actualValue = variableController.get(it.name)?.getValue()
|
||||
val expectedValue = it.value.wrapVariableValue()
|
||||
val actualValue = divView.expressionsRuntime?.variableController?.get(it.name)
|
||||
if (it.type == VALUE_TYPE_DICT || it.type == VALUE_TYPE_ARRAY) {
|
||||
Assert.assertEquals(expectedValue.toString(), actualValue.toString())
|
||||
} else {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"type": "string",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
@@ -42,7 +41,6 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"long_type": true,
|
||||
"type": "integer",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
@@ -69,7 +67,6 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"type": "number",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
@@ -96,7 +93,6 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"$ref": "common.json#/boolean_int",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
@@ -116,14 +112,12 @@
|
||||
"$description": "translations.json#/div_variable_name"
|
||||
},
|
||||
"type": {
|
||||
"supports_expressions": false,
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"color"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"$ref": "common.json#/color",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
@@ -149,7 +143,6 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"$ref": "common.json#/url",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
@@ -175,7 +168,6 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"type": "dict",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
@@ -202,7 +194,6 @@
|
||||
},
|
||||
"value": {
|
||||
"type": "array",
|
||||
"supports_expressions": false,
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android",
|
||||
"web"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user