mirror of
https://github.com/divkit/divkit.git
synced 2026-05-07 20:02:32 +00:00
Support expressions with dict in schema
commit_hash:30fce799ccb23434f200edd0798b01f7c17754a7
This commit is contained in:
@@ -20584,6 +20584,7 @@
|
||||
"test_data/integration_test_data/local_functions_number.json":"divkit/public/test_data/integration_test_data/local_functions_number.json",
|
||||
"test_data/integration_test_data/local_functions_string.json":"divkit/public/test_data/integration_test_data/local_functions_string.json",
|
||||
"test_data/integration_test_data/local_functions_url.json":"divkit/public/test_data/integration_test_data/local_functions_url.json",
|
||||
"test_data/integration_test_data/set_dict_variable.json":"divkit/public/test_data/integration_test_data/set_dict_variable.json",
|
||||
"test_data/interactive_snapshot_test_data/div-action/array-variable-mutation.json":"divkit/public/test_data/interactive_snapshot_test_data/div-action/array-variable-mutation.json",
|
||||
"test_data/interactive_snapshot_test_data/div-action/base.json":"divkit/public/test_data/interactive_snapshot_test_data/div-action/base.json",
|
||||
"test_data/interactive_snapshot_test_data/div-action/focus-actions.json":"divkit/public/test_data/interactive_snapshot_test_data/div-action/focus-actions.json",
|
||||
|
||||
@@ -20,6 +20,7 @@ from ...schema.modeling.entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
StringEnumeration,
|
||||
EntityEnumeration,
|
||||
@@ -46,6 +47,8 @@ def update_property_type_base(property_type: PropertyType):
|
||||
property_type.__class__ = DartColor
|
||||
elif isinstance(property_type, Dictionary):
|
||||
property_type.__class__ = DartDictionary
|
||||
elif isinstance(property_type, RawObject):
|
||||
property_type.__class__ = DartRawObject
|
||||
elif isinstance(property_type, RawArray):
|
||||
property_type.__class__ = DartRawArray
|
||||
elif isinstance(property_type, Double):
|
||||
@@ -208,7 +211,7 @@ class DartProperty(Property):
|
||||
return f"safeParseBool{expr}({src},{fallback})"
|
||||
elif isinstance(prop_type, (String, StaticString)):
|
||||
return f"safeParseStr{expr}({src},{fallback})"
|
||||
elif isinstance(prop_type, Dictionary):
|
||||
elif isinstance(prop_type, (Dictionary, RawObject)):
|
||||
return f"safeParseMap{expr}({src},{fallback})"
|
||||
elif isinstance(prop_type, RawArray):
|
||||
return f"safeParseList{expr}({src},{fallback})"
|
||||
@@ -233,7 +236,7 @@ class DartProperty(Property):
|
||||
strategy = "reqProp<bool>(safeParseBool(v),)"
|
||||
elif isinstance(list_item_type, (String, StaticString)):
|
||||
strategy = "reqProp<String>(safeParseStr(v),)"
|
||||
elif isinstance(list_item_type, Dictionary):
|
||||
elif isinstance(list_item_type, (Dictionary, RawObject)):
|
||||
strategy = "reqProp<Obj>(safeParseMap(v),)"
|
||||
elif isinstance(list_item_type, RawArray):
|
||||
strategy = "reqProp<Arr>(safeParseList(v),)"
|
||||
@@ -333,7 +336,7 @@ class DartPropertyType(PropertyType):
|
||||
return 'String'
|
||||
elif isinstance(self, Color):
|
||||
return 'Color'
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return 'Obj'
|
||||
elif isinstance(self, RawArray):
|
||||
return 'Arr'
|
||||
@@ -477,6 +480,10 @@ class DartDictionary(DartPropertyType, Dictionary):
|
||||
pass
|
||||
|
||||
|
||||
class DartRawObject(DartPropertyType, RawObject):
|
||||
pass
|
||||
|
||||
|
||||
class DartRawArray(DartPropertyType, RawArray):
|
||||
pass
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ from ...schema.modeling.entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
DivanGeneratorProperties,
|
||||
)
|
||||
@@ -123,6 +124,8 @@ def update_property_type_base(property_type: PropertyType):
|
||||
property_type.__class__ = DivanColor
|
||||
elif isinstance(property_type, Dictionary):
|
||||
property_type.__class__ = DivanDictionary
|
||||
elif isinstance(property_type, RawObject):
|
||||
property_type.__class__ = DivanRawObject
|
||||
elif isinstance(property_type, RawArray):
|
||||
property_type.__class__ = DivanRawArray
|
||||
elif isinstance(property_type, Double):
|
||||
@@ -628,7 +631,7 @@ class DivanPropertyType(PropertyType):
|
||||
return 'Color'
|
||||
elif isinstance(self, Url):
|
||||
return 'Url'
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return 'Map<String, Any>'
|
||||
elif isinstance(self, RawArray):
|
||||
return 'List<Any>'
|
||||
@@ -656,7 +659,7 @@ class DivanPropertyType(PropertyType):
|
||||
def is_primitive(self) -> bool:
|
||||
if isinstance(self, (Int, Double, Bool, BoolInt, String, StaticString, Color, Url, RawArray)):
|
||||
return True
|
||||
elif isinstance(self, (Dictionary, Array)):
|
||||
elif isinstance(self, (Dictionary, RawObject, Array)):
|
||||
return False
|
||||
elif isinstance(self, Object):
|
||||
inner_obj = self.object
|
||||
@@ -690,6 +693,10 @@ class DivanDictionary(DivanPropertyType, Dictionary):
|
||||
pass
|
||||
|
||||
|
||||
class DivanRawObject(DivanPropertyType, RawObject):
|
||||
pass
|
||||
|
||||
|
||||
class DivanRawArray(DivanPropertyType, RawArray):
|
||||
pass
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ from ...schema.modeling.entities import (
|
||||
BoolInt,
|
||||
Color,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
Double,
|
||||
Int,
|
||||
@@ -105,6 +106,8 @@ def update_property_type_base(property_type: PropertyType):
|
||||
property_type.__class__ = DocumentationColor
|
||||
elif isinstance(property_type, Dictionary):
|
||||
property_type.__class__ = DocumentationDictionary
|
||||
elif isinstance(property_type, RawObject):
|
||||
property_type.__class__ = DocumentationRawObject
|
||||
elif isinstance(property_type, RawArray):
|
||||
property_type.__class__ = DocumentationRawArray
|
||||
elif isinstance(property_type, Double):
|
||||
@@ -263,6 +266,16 @@ class DocumentationColor(Color, DocumentationPropertyType):
|
||||
|
||||
class DocumentationDictionary(Dictionary, DocumentationPropertyType):
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return 'dictionary'
|
||||
|
||||
def constraints(self, dictionary: Dict[str, str]) -> str:
|
||||
return ''
|
||||
|
||||
|
||||
class DocumentationRawObject(RawObject, DocumentationPropertyType):
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return 'object'
|
||||
@@ -271,7 +284,7 @@ class DocumentationDictionary(Dictionary, DocumentationPropertyType):
|
||||
return ''
|
||||
|
||||
|
||||
class DocumentationRawArray(Dictionary, DocumentationPropertyType):
|
||||
class DocumentationRawArray(RawArray, DocumentationPropertyType):
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
|
||||
@@ -22,6 +22,7 @@ from ...schema.modeling.entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
ObjectFormat,
|
||||
KotlinGeneratorProperties
|
||||
@@ -73,6 +74,7 @@ class KotlinEntity(Entity):
|
||||
Color.__bases__ = (KotlinPropertyType, PropertyType,)
|
||||
String.__bases__ = (KotlinPropertyType, PropertyType,)
|
||||
Dictionary.__bases__ = (KotlinPropertyType, PropertyType,)
|
||||
RawObject.__bases__ = (KotlinPropertyType, PropertyType,)
|
||||
RawArray.__bases__ = (KotlinPropertyType, PropertyType,)
|
||||
for prop in self.properties:
|
||||
prop.__class__ = KotlinProperty
|
||||
@@ -1280,7 +1282,7 @@ class KotlinPropertyType(PropertyType):
|
||||
args.append(f'{prop.declaration_name} = {declaration}')
|
||||
args = ', '.join(args)
|
||||
return wrap(f'{entity.resolved_prefixed_declaration}({args})')
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return wrap(f'JSONObject("""\n{default_value}\n""")')
|
||||
else:
|
||||
return None
|
||||
@@ -1335,7 +1337,7 @@ class KotlinPropertyType(PropertyType):
|
||||
return 'Boolean'
|
||||
elif isinstance(self, String):
|
||||
return 'CharSequence' if self.formatted else 'String'
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return 'JSONObject'
|
||||
elif isinstance(self, RawArray):
|
||||
return 'JSONArray'
|
||||
@@ -1513,6 +1515,8 @@ class KotlinPropertyType(PropertyType):
|
||||
return f'{prefix}INT'
|
||||
elif isinstance(self, Double):
|
||||
return f'{prefix}DOUBLE'
|
||||
elif isinstance(self, Dictionary):
|
||||
return f'{prefix}DICT'
|
||||
elif isinstance(self, RawArray):
|
||||
return f'{prefix}JSON_ARRAY'
|
||||
elif isinstance(self, Array):
|
||||
|
||||
@@ -18,6 +18,7 @@ from ...schema.modeling.entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray
|
||||
)
|
||||
from ... import utils
|
||||
@@ -47,6 +48,8 @@ def update_property_type_base(property_type: PropertyType):
|
||||
property_type.__class__ = KotlinDSLColor
|
||||
elif isinstance(property_type, Dictionary):
|
||||
property_type.__class__ = KotlinDSLDictionary
|
||||
elif isinstance(property_type, RawObject):
|
||||
property_type.__class__ = KotlinDSLRawObject
|
||||
elif isinstance(property_type, RawArray):
|
||||
property_type.__class__ = KotlinDSLRawArray
|
||||
elif isinstance(property_type, Double):
|
||||
@@ -274,7 +277,7 @@ class KotlinDSLPropertyType(PropertyType):
|
||||
return 'Color'
|
||||
elif isinstance(self, Url):
|
||||
return 'URI'
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return 'Map<String, Any>'
|
||||
elif isinstance(self, RawArray):
|
||||
return 'List<Any>'
|
||||
@@ -322,6 +325,10 @@ class KotlinDSLDictionary(KotlinDSLPropertyType, Dictionary):
|
||||
pass
|
||||
|
||||
|
||||
class KotlinDSLRawObject(KotlinDSLPropertyType, RawObject):
|
||||
pass
|
||||
|
||||
|
||||
class KotlinDSLRawArray(KotlinDSLPropertyType, RawArray):
|
||||
pass
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from ...schema.modeling.entities import (
|
||||
BoolInt,
|
||||
Color,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
Double,
|
||||
Int,
|
||||
@@ -43,6 +44,8 @@ def update_property_type_base(property_type: PropertyType):
|
||||
property_type.__class__ = PythonColor
|
||||
elif isinstance(property_type, Dictionary):
|
||||
property_type.__class__ = PythonDictionary
|
||||
elif isinstance(property_type, RawObject):
|
||||
property_type.__class__ = PythonRawObject
|
||||
elif isinstance(property_type, RawArray):
|
||||
property_type.__class__ = PythonRawArray
|
||||
elif isinstance(property_type, Double):
|
||||
@@ -288,7 +291,7 @@ class PythonPropertyType(PropertyType):
|
||||
return 'str'
|
||||
elif isinstance(self, StaticString):
|
||||
raise TypeError(f'{self} is a static type')
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return 'typing.Dict[str, typing.Any]'
|
||||
elif isinstance(self, RawArray):
|
||||
return 'typing.Sequence[typing.Any]'
|
||||
@@ -306,7 +309,7 @@ class PythonPropertyType(PropertyType):
|
||||
|
||||
@property
|
||||
def constraints(self) -> str:
|
||||
if isinstance(self, (Bool, BoolInt, Dictionary, RawArray)):
|
||||
if isinstance(self, (Bool, BoolInt, Dictionary, RawObject, RawArray)):
|
||||
return ''
|
||||
elif isinstance(self, Array):
|
||||
result = ''
|
||||
@@ -358,6 +361,10 @@ class PythonDictionary(PythonPropertyType, Dictionary):
|
||||
pass
|
||||
|
||||
|
||||
class PythonRawObject(PythonPropertyType, RawObject):
|
||||
pass
|
||||
|
||||
|
||||
class PythonRawArray(PythonPropertyType, RawArray):
|
||||
pass
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ from ... import utils
|
||||
from ...schema.modeling.entities import (
|
||||
Declarable,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
EntityEnumeration,
|
||||
Entity,
|
||||
Property,
|
||||
@@ -290,7 +291,7 @@ class SwiftGenerator(Generator):
|
||||
properties_to_declare = entity.properties_to_declare_swift
|
||||
if properties_to_declare:
|
||||
for prop in properties_to_declare:
|
||||
if isinstance(prop.property_type, Dictionary) or isinstance(prop.property_type, RawArray):
|
||||
if isinstance(prop.property_type, (Dictionary, RawObject, RawArray)):
|
||||
sendable_conformance = '@unchecked Sendable'
|
||||
protocols = list(filter(None, [entity.protocol_plus_super_entities(), sendable_conformance]))
|
||||
conformance = f': {", ".join(protocols)}'
|
||||
|
||||
@@ -20,6 +20,7 @@ from ...schema.modeling.entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
ObjectFormat,
|
||||
SwiftGeneratorProperties,
|
||||
@@ -84,6 +85,7 @@ class SwiftEntity(Entity):
|
||||
Color.__bases__ = (SwiftPropertyType, PropertyType,)
|
||||
String.__bases__ = (SwiftPropertyType, PropertyType,)
|
||||
Dictionary.__bases__ = (SwiftPropertyType, PropertyType,)
|
||||
RawObject.__bases__ = (SwiftPropertyType, PropertyType,)
|
||||
RawArray.__bases__ = (SwiftPropertyType, PropertyType,)
|
||||
for prop in self.properties:
|
||||
prop.__class__ = SwiftProperty
|
||||
@@ -476,6 +478,8 @@ class SwiftProperty(Property):
|
||||
return 'resolveNumeric'
|
||||
elif isinstance(property_type, Object) and isinstance(property_type.object, StringEnumeration):
|
||||
return 'resolveEnum'
|
||||
elif isinstance(property_type, Dictionary):
|
||||
return 'resolveDict'
|
||||
elif isinstance(property_type, RawArray):
|
||||
return 'resolveArray'
|
||||
elif isinstance(property_type, Array):
|
||||
@@ -678,7 +682,7 @@ class SwiftPropertyType(PropertyType):
|
||||
return 'URL'
|
||||
elif isinstance(self, Color):
|
||||
return 'Color'
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return '[String: Any]'
|
||||
elif isinstance(self, RawArray):
|
||||
return '[Any]'
|
||||
@@ -783,7 +787,7 @@ class SwiftPropertyType(PropertyType):
|
||||
args.append(f'{prop.declaration_name}: {default_value}')
|
||||
args = ', '.join(args)
|
||||
return f'{entity.declaration_prefix}{utils.capitalize_camel_case(entity.original_name)}({args})'
|
||||
elif isinstance(self, Dictionary):
|
||||
elif isinstance(self, (Dictionary, RawObject)):
|
||||
return f'(try! JSONSerialization.jsonObject(jsonString: """\n{default_value}\n""") as! [String: Any])'
|
||||
else:
|
||||
return None
|
||||
@@ -806,7 +810,7 @@ class SwiftPropertyType(PropertyType):
|
||||
|
||||
@property
|
||||
def is_equatable(self) -> bool:
|
||||
if isinstance(self, (Dictionary, RawArray)):
|
||||
if isinstance(self, (Dictionary, RawObject, RawArray)):
|
||||
return False
|
||||
elif isinstance(self, Array):
|
||||
return cast(SwiftPropertyType, self.property_type).is_equatable
|
||||
@@ -814,9 +818,9 @@ class SwiftPropertyType(PropertyType):
|
||||
return True
|
||||
|
||||
def serialization_suffix(self, use_expressions: bool) -> str:
|
||||
if isinstance(self, (Dictionary)):
|
||||
if isinstance(self, RawObject):
|
||||
return ''
|
||||
elif isinstance(self, (String, Int, Double, Bool, BoolInt, RawArray)):
|
||||
elif isinstance(self, (String, Int, Double, Bool, BoolInt, Dictionary, RawArray)):
|
||||
return '.toValidSerializationValue()' if use_expressions else ''
|
||||
elif isinstance(self, Object):
|
||||
if isinstance(self.object, StringEnumeration):
|
||||
|
||||
@@ -16,6 +16,7 @@ from ...schema.modeling.entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
RawArray,
|
||||
Declarable,
|
||||
TypeScriptGeneratorProperties
|
||||
@@ -67,7 +68,7 @@ def _type_script_type_name(property_type: PropertyType, supports_expressions: bo
|
||||
return 'string'
|
||||
elif isinstance(property_type, StaticString):
|
||||
raise TypeError('Is a static type')
|
||||
elif isinstance(property_type, Dictionary):
|
||||
elif isinstance(property_type, (Dictionary, RawObject)):
|
||||
return '{}'
|
||||
elif isinstance(property_type, RawArray):
|
||||
return 'unknown[]'
|
||||
|
||||
@@ -30,6 +30,7 @@ from .entities import (
|
||||
Color,
|
||||
String,
|
||||
Dictionary,
|
||||
RawObject,
|
||||
BoolInt,
|
||||
RawArray,
|
||||
_build_documentation_generator_properties
|
||||
@@ -276,9 +277,11 @@ def type_property_build(dictionary: Dict[str, any],
|
||||
mode=mode,
|
||||
config=config)
|
||||
return Array(property_type=property_type, min_items=min_items), declarations
|
||||
elif type_value == 'dict':
|
||||
return Dictionary(), []
|
||||
elif type_value == 'object':
|
||||
if dictionary.get('additionalProperties', False) and 'properties' not in dictionary:
|
||||
return Dictionary(), []
|
||||
return RawObject(), []
|
||||
entity: Entity = Entity(name=name,
|
||||
original_name=outer_name,
|
||||
dictionary=dictionary,
|
||||
|
||||
@@ -797,9 +797,9 @@ def default_value(lang: GeneratedLanguage,
|
||||
class PropertyType(ABC):
|
||||
@property
|
||||
def supports_expressions(self) -> bool:
|
||||
if isinstance(self, (Int, Double, Bool, BoolInt, String, Color, Url, RawArray)):
|
||||
if isinstance(self, (Int, Double, Bool, BoolInt, String, Color, Url, RawArray, Dictionary)):
|
||||
return True
|
||||
elif isinstance(self, (Dictionary, StaticString)):
|
||||
elif isinstance(self, (RawObject, StaticString)):
|
||||
return False
|
||||
elif isinstance(self, Array):
|
||||
if isinstance(self.property_type, Object) and \
|
||||
@@ -837,7 +837,7 @@ class PropertyType(ABC):
|
||||
|
||||
@property
|
||||
def as_json(self) -> Dict:
|
||||
if isinstance(self, (Int, Double, Bool, BoolInt, String, StaticString, Color, Url, Dictionary)):
|
||||
if isinstance(self, (Int, Double, Bool, BoolInt, String, StaticString, Color, Url, Dictionary, RawObject)):
|
||||
return {
|
||||
'value': str(type(self).__name__)
|
||||
}
|
||||
@@ -907,6 +907,11 @@ class Dictionary(PropertyType):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class RawObject(PropertyType):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
class RawArray(PropertyType):
|
||||
min_items: int
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.yandex.div.internal.parser
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
interface TypeHelper<T> {
|
||||
|
||||
@@ -63,3 +64,9 @@ val TYPE_HELPER_JSON_ARRAY = object : TypeHelper<JSONArray> {
|
||||
override val typeDefault = JSONArray()
|
||||
override fun isTypeValid(value: Any) = value is JSONArray
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val TYPE_HELPER_DICT = object : TypeHelper<JSONObject> {
|
||||
override val typeDefault = JSONObject()
|
||||
override fun isTypeValid(value: Any) = value is JSONObject
|
||||
}
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ internal class DivActionTypedSetStoredValueHandler @Inject constructor() : DivAc
|
||||
is DivTypedValue.Color -> StoredValue.ColorStoredValue(name, Color(value.value.value.evaluate(resolver)))
|
||||
is DivTypedValue.Url -> StoredValue.UrlStoredValue(name, Url.from(value.value.value.evaluate(resolver).toString()))
|
||||
is DivTypedValue.Array -> StoredValue.ArrayStoredValue(name, value.value.value.evaluate(resolver))
|
||||
is DivTypedValue.Dict -> StoredValue.DictStoredValue(name, value.value.value)
|
||||
is DivTypedValue.Dict -> StoredValue.DictStoredValue(name, value.value.value.evaluate(resolver))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ internal fun DivTypedValue.evaluate(expressionResolver: ExpressionResolver): Any
|
||||
is DivTypedValue.Number -> value.value.evaluate(expressionResolver)
|
||||
is DivTypedValue.Url -> value.value.evaluate(expressionResolver)
|
||||
is DivTypedValue.Array -> value.value.evaluate(expressionResolver)
|
||||
is DivTypedValue.Dict -> value.value
|
||||
is DivTypedValue.Dict -> value.value.evaluate(expressionResolver)
|
||||
}
|
||||
return newValue
|
||||
}
|
||||
@@ -46,7 +46,7 @@ internal fun DivTypedValue.longValue(expressionResolver: ExpressionResolver): Lo
|
||||
internal fun DivTypedValue.doubleValue(expressionResolver: ExpressionResolver): Double? {
|
||||
return when (this) {
|
||||
is DivTypedValue.Integer -> value.value.evaluate(expressionResolver).toDouble()
|
||||
is DivTypedValue.Number -> value.value.evaluate(expressionResolver).toDouble()
|
||||
is DivTypedValue.Number -> value.value.evaluate(expressionResolver)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -33,8 +33,8 @@ object ExpressionTestCaseUtils {
|
||||
private const val VALUE_TYPE_DATE_TIME = "datetime"
|
||||
private const val VALUE_TYPE_URL = "url"
|
||||
private const val VALUE_TYPE_COLOR = "color"
|
||||
private const val VALUE_TYPE_DICT = "dict"
|
||||
private const val VALUE_TYPE_ARRAY = "array"
|
||||
const val VALUE_TYPE_DICT = "dict"
|
||||
const val VALUE_TYPE_ARRAY = "array"
|
||||
private const val VALUE_TYPE_UNIT = "unit"
|
||||
private const val VALUE_TYPE_ERROR = "error"
|
||||
private const val VALUE_TYPE_VARIABLE = "variable"
|
||||
|
||||
+11
-2
@@ -6,6 +6,8 @@ import com.yandex.div.DivDataTag
|
||||
import com.yandex.div.core.Div2Context
|
||||
import com.yandex.div.core.DivConfiguration
|
||||
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.images.DivImageDownloadCallback
|
||||
import com.yandex.div.core.images.DivImageLoader
|
||||
@@ -53,8 +55,15 @@ class IntegrationMultiplatformTest(testCase: TestCaseOrError<IntegrationTestCase
|
||||
logger.messages.contains(it.message)
|
||||
)
|
||||
}
|
||||
is IntegrationTestCase.ExpectedResult.Variable ->
|
||||
Assert.assertEquals(it.value, variableController.get(it.name)?.getValue())
|
||||
is IntegrationTestCase.ExpectedResult.Variable -> {
|
||||
val expectedValue = it.value
|
||||
val actualValue = variableController.get(it.name)?.getValue()
|
||||
if (it.type == VALUE_TYPE_DICT || it.type == VALUE_TYPE_ARRAY) {
|
||||
Assert.assertEquals(expectedValue.toString(), actualValue.toString())
|
||||
} else {
|
||||
Assert.assertEquals(expectedValue, actualValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.yandex.div.interactive
|
||||
|
||||
import com.yandex.div.core.expression.ExpressionTestCaseUtils.getVariableValue
|
||||
import com.yandex.div.core.expression.ExpressionTestCaseUtils.type
|
||||
import com.yandex.div2.DivAction
|
||||
import com.yandex.div2.DivData
|
||||
import org.json.JSONObject
|
||||
@@ -16,7 +17,7 @@ class IntegrationTestCase(
|
||||
sealed interface ExpectedResult {
|
||||
|
||||
class Variable(val name: String, json: JSONObject): ExpectedResult {
|
||||
val type: String = json.getString("type")
|
||||
val type: String = json.type
|
||||
val value = json.getVariableValue(type)
|
||||
}
|
||||
|
||||
|
||||
@@ -89,3 +89,14 @@ extension Expression where T: RawRepresentable, T.RawValue == String {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Expression where T == [String: Any] {
|
||||
func toValidSerializationValue() -> ValidSerializationValue {
|
||||
switch self {
|
||||
case let .value(value):
|
||||
value
|
||||
case let .link(link):
|
||||
link.rawValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,9 @@ extension DivTypedValue {
|
||||
}
|
||||
return nil
|
||||
case let .dictValue(value):
|
||||
if let dictValue = DivDictionary.fromAny(value.value) {
|
||||
return .dict(dictValue)
|
||||
if let dictValue = value.resolveValue(expressionResolver),
|
||||
let divDict = DivDictionary.fromAny(dictValue) {
|
||||
return .dict(divDict)
|
||||
}
|
||||
return nil
|
||||
case let .integerValue(value):
|
||||
@@ -69,7 +70,10 @@ extension DivTypedValue {
|
||||
}
|
||||
return nil
|
||||
case let .dictValue(value):
|
||||
return DivDictionary.fromAny(value.value)
|
||||
if let dictValue = value.resolveValue(expressionResolver) {
|
||||
return DivDictionary.fromAny(dictValue)
|
||||
}
|
||||
return nil
|
||||
case let .integerValue(value):
|
||||
if let integerValue = value.resolveValue(expressionResolver) {
|
||||
return integerValue
|
||||
|
||||
@@ -6,10 +6,14 @@ import VGSL
|
||||
|
||||
public final class DictValue: @unchecked Sendable {
|
||||
public static let type: String = "dict"
|
||||
public let value: [String: Any]
|
||||
public let value: Expression<[String: Any]>
|
||||
|
||||
public func resolveValue(_ resolver: ExpressionResolver) -> [String: Any]? {
|
||||
resolver.resolveDict(value)
|
||||
}
|
||||
|
||||
init(
|
||||
value: [String: Any]
|
||||
value: Expression<[String: Any]>
|
||||
) {
|
||||
self.value = value
|
||||
}
|
||||
@@ -28,7 +32,7 @@ extension DictValue: Serializable {
|
||||
public func toDictionary() -> [String: ValidSerializationValue] {
|
||||
var result: [String: ValidSerializationValue] = [:]
|
||||
result["type"] = Self.type
|
||||
result["value"] = value
|
||||
result["value"] = value.toValidSerializationValue()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,18 +7,18 @@ import VGSL
|
||||
public final class DictValueTemplate: TemplateValue, @unchecked Sendable {
|
||||
public static let type: String = "dict"
|
||||
public let parent: String?
|
||||
public let value: Field<[String: Any]>?
|
||||
public let value: Field<Expression<[String: Any]>>?
|
||||
|
||||
public convenience init(dictionary: [String: Any], templateToType: [TemplateName: String]) throws {
|
||||
self.init(
|
||||
parent: dictionary["type"] as? String,
|
||||
value: dictionary.getOptionalField("value")
|
||||
value: dictionary.getOptionalExpressionField("value")
|
||||
)
|
||||
}
|
||||
|
||||
init(
|
||||
parent: String?,
|
||||
value: Field<[String: Any]>? = nil
|
||||
value: Field<Expression<[String: Any]>>? = nil
|
||||
) {
|
||||
self.parent = parent
|
||||
self.value = value
|
||||
@@ -47,7 +47,7 @@ public final class DictValueTemplate: TemplateValue, @unchecked Sendable {
|
||||
if useOnlyLinks {
|
||||
return resolveOnlyLinks(context: context, parent: parent)
|
||||
}
|
||||
var valueValue: DeserializationResult<[String: Any]> = { parent?.value?.value() ?? .noValue }()
|
||||
var valueValue: DeserializationResult<Expression<[String: Any]>> = { parent?.value?.value() ?? .noValue }()
|
||||
_ = {
|
||||
// Each field is parsed in its own lambda to keep the stack size managable
|
||||
// Otherwise the compiler will allocate stack for each intermediate variable
|
||||
|
||||
@@ -247,7 +247,7 @@ final class DivActionHandlerTests: XCTestCase {
|
||||
handle(.divActionArraySetValue(
|
||||
DivActionArraySetValue(
|
||||
index: .value(1),
|
||||
value: .dictValue(DictValue(value: ["key1": "value", "key2": 123.45])),
|
||||
value: dictValue(["key1": "value", "key2": 123.45]),
|
||||
variableName: .value("array_var")
|
||||
)
|
||||
))
|
||||
@@ -306,7 +306,7 @@ final class DivActionHandlerTests: XCTestCase {
|
||||
handle(.divActionDictSetValue(
|
||||
DivActionDictSetValue(
|
||||
key: .value("key"),
|
||||
value: .dictValue(DictValue(value: ["new_key": "new value"])),
|
||||
value: dictValue(["new_key": "new value"]),
|
||||
variableName: .value("dict_var")
|
||||
)
|
||||
))
|
||||
@@ -325,7 +325,7 @@ final class DivActionHandlerTests: XCTestCase {
|
||||
divAction(
|
||||
typed: .divActionDictSetValue(DivActionDictSetValue(
|
||||
key: .value("key"),
|
||||
value: .dictValue(DictValue(value: ["new_key": "new value"])),
|
||||
value: dictValue(["new_key": "new value"]),
|
||||
variableName: .value("dict_var")
|
||||
))
|
||||
),
|
||||
@@ -507,7 +507,7 @@ final class DivActionHandlerTests: XCTestCase {
|
||||
let value: [String: Any] = ["key1": "value", "key2": 123.45, "nested": ["key": "value"]]
|
||||
handle(.divActionSetVariable(
|
||||
DivActionSetVariable(
|
||||
value: .dictValue(DictValue(value: value)),
|
||||
value: dictValue(value),
|
||||
variableName: .value("dict_var")
|
||||
)
|
||||
))
|
||||
@@ -621,6 +621,10 @@ private func stringValue(_ value: String) -> DivTypedValue {
|
||||
.stringValue(StringValue(value: .value(value)))
|
||||
}
|
||||
|
||||
private func dictValue(_ value: [String: Any]) -> DivTypedValue {
|
||||
.dictValue(DictValue(value: .value(value)))
|
||||
}
|
||||
|
||||
private let cardId: DivCardID = "test_card"
|
||||
|
||||
private final class MockReporter: DivReporter {
|
||||
|
||||
@@ -123,7 +123,7 @@ final class SetStoredValueActionHandlerTests: XCTestCase {
|
||||
handle(
|
||||
action(
|
||||
name: "name",
|
||||
value: .dictValue(DictValue(value: ["key": "value"]))
|
||||
value: .dictValue(DictValue(value: .value(["key": "value"])))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -120,8 +120,7 @@
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
"type": "dict"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -176,8 +176,7 @@
|
||||
},
|
||||
"value": {
|
||||
"supports_expressions": false,
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"type": "dict",
|
||||
"$description": "translations.json#/div_variable_value"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"description": "Set dict variable from variable.",
|
||||
"div_data": {
|
||||
"card": {
|
||||
"log_id": "dict_variable",
|
||||
"variables": [
|
||||
{
|
||||
"name": "dict_var",
|
||||
"type": "dict",
|
||||
"value": {
|
||||
"boolean": true,
|
||||
"integer": 1,
|
||||
"number": 1.0,
|
||||
"string": "value"
|
||||
}
|
||||
}
|
||||
],
|
||||
"states": [
|
||||
{
|
||||
"state_id": 0,
|
||||
"div": {
|
||||
"type": "text",
|
||||
"text": "text"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"div_actions": [
|
||||
{
|
||||
"log_id": "check usual action",
|
||||
"url": "div-action://set_variable?name=result&value=@{dict_var}"
|
||||
}
|
||||
],
|
||||
"expected": [
|
||||
{
|
||||
"type": "variable",
|
||||
"variable_name": "result",
|
||||
"value": {
|
||||
"type": "dict",
|
||||
"value": {
|
||||
"boolean": true,
|
||||
"integer": 1,
|
||||
"number": 1.0,
|
||||
"string": "value"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
{
|
||||
"div_actions": [
|
||||
{
|
||||
"log_id": "check typed action",
|
||||
"typed": {
|
||||
"type": "set_variable",
|
||||
"variable_name": "result",
|
||||
"value": {
|
||||
"type": "dict",
|
||||
"value": "@{dict_var}"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"expected": [
|
||||
{
|
||||
"type": "variable",
|
||||
"variable_name": "result",
|
||||
"value": {
|
||||
"type": "dict",
|
||||
"value": {
|
||||
"boolean": true,
|
||||
"integer": 1,
|
||||
"number": 1.0,
|
||||
"string": "value"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"platforms": [
|
||||
"android"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user