add getValue functions

This commit is contained in:
tayrinn
2023-03-22 13:52:04 +03:00
parent 3e496e6af6
commit f5ea7be16d
12 changed files with 198 additions and 19 deletions
@@ -1,6 +1,6 @@
package com.yandex.div.evaluable
abstract class Function {
abstract class Function(open val variableProvider: VariableProvider? = null) {
abstract val name: String
abstract val declaredArgs: List<FunctionArgument>
@@ -1,11 +1,9 @@
package com.yandex.div.evaluable.function
import com.yandex.div.evaluable.EvaluableType
import com.yandex.div.evaluable.*
import com.yandex.div.evaluable.Function
import com.yandex.div.evaluable.FunctionArgument
import com.yandex.div.evaluable.FunctionProvider
object BuiltinFunctionProvider : FunctionProvider {
class BuiltinFunctionProvider(variableProvider: VariableProvider) : FunctionProvider {
private val registry = FunctionRegistry()
@@ -139,6 +137,14 @@ object BuiltinFunctionProvider : FunctionProvider {
registry.register(NumberToString)
registry.register(BooleanToString)
registry.register(ColorToString)
// Variable functions
registry.register(GetIntegerValue(variableProvider))
registry.register(GetNumberValue(variableProvider))
registry.register(GetStringValue(variableProvider))
registry.register(GetColorValueString(variableProvider))
registry.register(GetColorValue(variableProvider))
registry.register(GetBooleanValue(variableProvider))
}
override fun get(name: String, args: List<EvaluableType>): Function {
@@ -0,0 +1,146 @@
package com.yandex.div.evaluable.function
import com.yandex.div.evaluable.*
import com.yandex.div.evaluable.Function
import com.yandex.div.evaluable.types.Color
internal class GetIntegerValue(override val variableProvider: VariableProvider) : Function(variableProvider) {
override val name = "getIntegerValue"
override val declaredArgs = listOf(
FunctionArgument(type = EvaluableType.STRING), // variable name
FunctionArgument(type = EvaluableType.INTEGER), // fallback
)
override val resultType = EvaluableType.INTEGER
override val isPure = false
override fun evaluate(args: List<Any>): Any {
val variableName = args[0] as String
val fallbackValue = args[1] as Int
val variableValue = variableProvider.get(variableName) as? Int
return variableValue ?: fallbackValue
}
}
internal class GetNumberValue(override val variableProvider: VariableProvider) : Function(variableProvider) {
override val name = "getNumberValue"
override val declaredArgs = listOf(
FunctionArgument(type = EvaluableType.STRING), // variable name
FunctionArgument(type = EvaluableType.NUMBER), // fallback
)
override val resultType = EvaluableType.NUMBER
override val isPure = false
override fun evaluate(args: List<Any>): Any {
val variableName = args[0] as String
val fallbackValue = args[1] as Number
val variableValue = if (variableProvider.get(variableName) is Int)
null
else
variableProvider.get(variableName) as? Number
return variableValue ?: fallbackValue
}
}
internal class GetStringValue(override val variableProvider: VariableProvider) : Function(variableProvider) {
override val name = "getStringValue"
override val declaredArgs = listOf(
FunctionArgument(type = EvaluableType.STRING), // variable name
FunctionArgument(type = EvaluableType.STRING), // fallback
)
override val resultType = EvaluableType.STRING
override val isPure = false
override fun evaluate(args: List<Any>): Any {
val variableName = args[0] as String
val fallbackValue = args[1] as String
val variableValue = variableProvider.get(variableName) as? String
return variableValue ?: fallbackValue
}
}
internal class GetColorValueString(override val variableProvider: VariableProvider) : Function(variableProvider) {
override val name = "getColorValue"
override val declaredArgs = listOf(
FunctionArgument(type = EvaluableType.STRING), // variable name
FunctionArgument(type = EvaluableType.STRING), // fallback
)
override val resultType = EvaluableType.COLOR
override val isPure = false
override fun evaluate(args: List<Any>): Any {
val variableName = args[0] as String
val fallbackValue = Color.parse(args[1] as String)
val variableValue = variableProvider.get(variableName) as? Color
return variableValue ?: fallbackValue
}
}
internal class GetColorValue(override val variableProvider: VariableProvider) : Function(variableProvider) {
override val name = "getColorValue"
override val declaredArgs = listOf(
FunctionArgument(type = EvaluableType.STRING), // variable name
FunctionArgument(type = EvaluableType.COLOR), // fallback
)
override val resultType = EvaluableType.COLOR
override val isPure = false
override fun evaluate(args: List<Any>): Any {
val variableName = args[0] as String
val fallbackValue = args[1] as Color
val variableValue = variableProvider.get(variableName) as? Color
return variableValue ?: fallbackValue
}
}
internal class GetBooleanValue(override val variableProvider: VariableProvider) : Function(variableProvider) {
override val name = "getBooleanValue"
override val declaredArgs = listOf(
FunctionArgument(type = EvaluableType.STRING), // variable name
FunctionArgument(type = EvaluableType.BOOLEAN), // fallback
)
override val resultType = EvaluableType.BOOLEAN
override val isPure = false
override fun evaluate(args: List<Any>): Any {
val variableName = args[0] as String
val fallbackValue = args[1] as Boolean
val variableValue = variableProvider.get(variableName) as? Boolean
return variableValue ?: fallbackValue
}
}
@@ -14,7 +14,7 @@ private typealias NumOfInvokes = Int
class EvaluableTest {
private val variableProvider = mock<VariableProvider>()
private val functionProvider = BuiltinFunctionProvider
private val functionProvider = BuiltinFunctionProvider(variableProvider)
private val evaluator = Evaluator(variableProvider, functionProvider)
// Ternary Operator Test
@@ -25,7 +25,7 @@ import java.io.File
class EvaluableMultiplatformTest(private val caseOrError: TestCaseOrError<ExpressionTestCase>) {
private val variableProvider = mock<VariableProvider>()
private val evaluator = Evaluator(variableProvider, BuiltinFunctionProvider)
private val evaluator = Evaluator(variableProvider, BuiltinFunctionProvider(variableProvider))
private lateinit var testCase: ExpressionTestCase
@Before
@@ -3,6 +3,7 @@ package com.yandex.div.evaluable.multiplatform
import com.yandex.div.evaluable.EvaluableException
import com.yandex.div.evaluable.EvaluableType
import com.yandex.div.evaluable.FunctionArgument
import com.yandex.div.evaluable.VariableProvider
import com.yandex.div.evaluable.function.BuiltinFunctionProvider
import com.yandex.div.evaluable.multiplatform.MultiplatformTestUtils.isForAndroidPlatform
import com.yandex.div.evaluable.multiplatform.MultiplatformTestUtils.parsePlatform
@@ -12,12 +13,15 @@ import org.json.JSONObject
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.Mockito.mock
import org.mockito.kotlin.mock
import java.io.File
import java.lang.RuntimeException
@RunWith(Parameterized::class)
class SignaturesMultiplatformTest(caseOrError: TestCaseOrError<SignatureTestCase>) {
private val functionProvider = BuiltinFunctionProvider
private val variableProvider = mock<VariableProvider>()
private val functionProvider = BuiltinFunctionProvider(variableProvider)
private val signature = caseOrError.getCaseOrThrow()
@Test
@@ -13,7 +13,7 @@ import com.yandex.div.evaluable.types.DateTime
internal object EvaluableReplRuntime {
private val variableProvider = VariableProvider { variableName -> variableList[variableName] }
private val functionProvider = BuiltinFunctionProvider
private val functionProvider = BuiltinFunctionProvider(variableProvider)
private val evaluator = Evaluator(variableProvider, functionProvider)
private val variableList = mutableMapOf<String, Any?>()
@@ -80,7 +80,7 @@ class DivKit private constructor(
@AnyThread
fun warmUpStatics() {
// Bootstraps all built in expression functions.
BuiltinFunctionProvider
BuiltinFunctionProvider { _ -> null }
}
@JvmStatic
@@ -83,7 +83,9 @@ internal class ExpressionsRuntimeProvider @Inject constructor(
addSource(globalVariableController.variableSource)
}
val evaluatorFactory = ExpressionEvaluatorFactory(BuiltinFunctionProvider)
val evaluatorFactory = ExpressionEvaluatorFactory(BuiltinFunctionProvider {
variableName -> variableController.getMutableVariable(variableName)?.getValue()
})
val errorCollector = errorCollectors.getOrCreate(tag, data)
val expressionResolver = ExpressionResolverImpl(
variableController,
@@ -7,6 +7,7 @@ import com.yandex.div.data.Variable
import com.yandex.div.evaluable.EvaluableType
import com.yandex.div.evaluable.Function
import com.yandex.div.evaluable.FunctionProvider
import com.yandex.div.evaluable.VariableProvider
import com.yandex.div.evaluable.function.BuiltinFunctionProvider
import com.yandex.div.evaluable.types.DateTime
import com.yandex.div.internal.parser.*
@@ -28,6 +29,7 @@ import java.util.*
class ExpressionResolverImplTest {
@get:Rule
val rule = EnableAssertsRule(false)
private val variableProvider = mock<VariableProvider>()
private val variables = mutableMapOf<String, Variable>().also { map ->
listOf(
@@ -66,7 +68,7 @@ class ExpressionResolverImplTest {
private val underTest = ExpressionResolverImpl(
externalVariables,
ExpressionEvaluatorFactory(BuiltinFunctionProvider),
ExpressionEvaluatorFactory(BuiltinFunctionProvider(variableProvider)),
mock(),
)
@@ -76,7 +78,7 @@ class ExpressionResolverImplTest {
ExpressionEvaluatorFactory(object : FunctionProvider {
override fun get(name: String, args: List<EvaluableType>): Function {
callback()
return BuiltinFunctionProvider.get(name, args)
return BuiltinFunctionProvider(variableProvider).get(name, args)
}
}),
mock()
@@ -197,7 +197,7 @@
}
],
"result_type": "integer",
"platforms": ["web"]
"platforms": [ "android", "web" ]
},
{
"name": "getNumberValue(string, number) number",
@@ -214,7 +214,7 @@
}
],
"result_type": "number",
"platforms": ["web"]
"platforms": [ "android", "web" ]
},
{
"name": "getStringValue(string, string) string",
@@ -231,7 +231,7 @@
}
],
"result_type": "string",
"platforms": ["web"]
"platforms": [ "android", "web" ]
},
{
"name": "getUrlValue(string, url) url",
@@ -282,7 +282,7 @@
}
],
"result_type": "color",
"platforms": ["web"]
"platforms": [ "android", "web" ]
},
{
"name": "getColorValue(string, string) color",
@@ -299,7 +299,7 @@
}
],
"result_type": "color",
"platforms": ["web"]
"platforms": [ "android", "web" ]
},
{
"name": "getBooleanValue(string, boolean) boolean",
@@ -316,7 +316,7 @@
}
],
"result_type": "boolean",
"platforms": ["web"]
"platforms": [ "android", "web" ]
}
]
}
@@ -15,6 +15,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -33,6 +34,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -45,6 +47,7 @@
},
"variables": [],
"platforms": [
"android",
"web"
]
},
@@ -63,6 +66,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -81,6 +85,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -93,6 +98,7 @@
},
"variables": [],
"platforms": [
"android",
"web"
]
},
@@ -111,6 +117,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -129,6 +136,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -141,6 +149,7 @@
},
"variables": [],
"platforms": [
"android",
"web"
]
},
@@ -159,6 +168,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -177,6 +187,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -189,6 +200,7 @@
},
"variables": [],
"platforms": [
"android",
"web"
]
},
@@ -212,6 +224,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -235,6 +248,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -253,6 +267,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -271,6 +286,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -289,6 +305,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -319,6 +336,7 @@
}
],
"platforms": [
"android",
"web"
]
},
@@ -349,6 +367,7 @@
},
"variables": [],
"platforms": [
"android",
"web"
]
},