Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

feat: add support to bind in Display #1086

Merged
merged 24 commits into from
Oct 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7661f5a
fix: parse color when is RGB size (#1033)
matheusribeirozup Oct 16, 2020
0ee2166
fix: adjust http client default to handle exception when set body (#1…
uziasferreirazup Oct 20, 2020
1c2e88c
remove shared code bettween backend and android
uziasferreirazup Oct 20, 2020
45fd4e5
adjust detekt
uziasferreirazup Oct 20, 2020
f06bddc
refactor: move module kotlin-core to inside beagle to possible add bi…
uziasferreirazup Oct 20, 2020
ff2d230
fix: adjust override title when navigate in screen (#1052)
viniciusguardieirozup Oct 20, 2020
541a18c
fix: adjust context evaluation to return correct types (#1043)
uziasferreirazup Oct 20, 2020
5341d23
Merge branch 'release/1.3.1-android' into feat/add-support-to-bind
uziasferreirazup Oct 20, 2020
2517df4
Merge branch 'release/1.3.1-android' into feat/add-support-to-bind
uziasferreirazup Oct 20, 2020
73c4cd2
adjust suppor to bind
uziasferreirazup Oct 21, 2020
273797a
Merge branch 'master' into refactor/adjust-module-kotlin-core
uziasferreirazup Oct 22, 2020
fef966f
Merge branch 'refactor/adjust-module-kotlin-core' into feat/add-suppo…
uziasferreirazup Oct 22, 2020
d151e06
remove module kotlin-core
uziasferreirazup Oct 22, 2020
e7d0d20
Merge branch 'master' into feat/add-support-to-bind
uziasferreirazup Oct 26, 2020
d816871
fix: adjust support to bind
uziasferreirazup Oct 26, 2020
4d67abe
adjust code
uziasferreirazup Oct 26, 2020
fdb4511
remove code used to test
uziasferreirazup Oct 26, 2020
28e3e9f
create unit test to mapper and flex view
uziasferreirazup Oct 26, 2020
851f579
adjust import
uziasferreirazup Oct 26, 2020
bb07a6f
adjust function
uziasferreirazup Oct 26, 2020
bf81b07
adjust layout change
uziasferreirazup Oct 26, 2020
6551fc7
adjust unit test
uziasferreirazup Oct 26, 2020
4b38fa5
adjust unit test
uziasferreirazup Oct 26, 2020
4249dfa
adjust unit test
uziasferreirazup Oct 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package br.com.zup.beagle.android.context

import br.com.zup.beagle.android.data.serializer.BeagleMoshi
import kotlin.reflect.KClass
import kotlin.reflect.full.isSubclassOf
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
Expand All @@ -31,14 +33,23 @@ internal fun ContextData.normalize(): ContextData {
}

internal fun Any.normalizeContextValue(): Any {
return if (isValueNormalized()) {
this
} else {
val newValue = BeagleMoshi.moshi.adapter(Any::class.java).toJson(this) ?: ""
newValue.normalizeContextValue()
return when {
isValueNormalized() -> {
this
}
isEnum(this::class) -> {
this.toString()
}
else -> {
val newValue = BeagleMoshi.moshi.adapter(Any::class.java).toJson(this) ?: ""
newValue.normalizeContextValue()
}
}
}

private fun isEnum(type: KClass<out Any>) = type.isSubclassOf(Enum::class)


internal fun String.normalizeContextValue(): Any {
return try {
JSONObject(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package br.com.zup.beagle.android.engine.mapper

import android.view.View
import br.com.zup.beagle.android.utils.dp
import br.com.zup.beagle.android.utils.internalObserveBindChanges
import br.com.zup.beagle.android.widget.RootView
import br.com.zup.beagle.core.Style
import br.com.zup.beagle.widget.core.EdgeValue
import br.com.zup.beagle.widget.core.Size
Expand All @@ -31,7 +34,7 @@ import com.facebook.yoga.YogaNode
import com.facebook.yoga.YogaPositionType
import com.facebook.yoga.YogaWrap

class FlexMapper {
internal class FlexMapper {

fun makeYogaNode(style: Style): YogaNode = YogaNode.create().apply {
flexDirection = makeYogaFlexDirection(style.flex?.flexDirection) ?: YogaFlexDirection.COLUMN
Expand All @@ -40,16 +43,30 @@ class FlexMapper {
alignItems = makeYogaAlignItems(style.flex?.alignItems) ?: YogaAlign.STRETCH
alignSelf = makeYogaAlignSelf(style.flex?.alignSelf) ?: YogaAlign.AUTO
alignContent = makeYogaAlignContent(style.flex?.alignContent) ?: YogaAlign.FLEX_START
if(style.flex?.flex == null) {
if (style.flex?.flex == null) {
flexGrow = style.flex?.grow?.toFloat() ?: 0.0f
flexShrink = style.flex?.shrink?.toFloat() ?: 1.0f
}
style.flex?.flex?.toFloat()?.let { flex = it }
display = makeYogaDisplay(style.display) ?: YogaDisplay.FLEX

display = YogaDisplay.FLEX
positionType = makeYogaPositionType(style.positionType) ?: YogaPositionType.RELATIVE
applyAttributes(style, this)
}

fun observeBindChangesFlex(style: Style,
rootView: RootView,
view: View,
yogaNode: YogaNode) {

if (style.display != null) {
internalObserveBindChanges(rootView, view, style.display) {
yogaNode.display = makeYogaDisplay(it) ?: YogaDisplay.FLEX
view.requestLayout()
}
}
}

private fun applyAttributes(style: Style, yogaNode: YogaNode) {
setWidth(style.size, yogaNode)
setHeight(style.size, yogaNode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ fun <T> ServerDrivenComponent.observeBindChanges(
view: View,
bind: Bind<T>,
observes: Observer<T?>
) {
internalObserveBindChanges(rootView, view, bind, observes)
}

internal fun <T> internalObserveBindChanges(
rootView: RootView,
view: View,
bind: Bind<T>,
observes: Observer<T?>
) {
val value = bind.observe(rootView, view, observes)
if (bind is Bind.Value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ import br.com.zup.beagle.core.GhostComponent
import br.com.zup.beagle.core.ServerDrivenComponent
import br.com.zup.beagle.core.Style
import br.com.zup.beagle.core.StyleComponent
import com.facebook.yoga.YogaNode
import com.facebook.yoga.YogaNodeJNIBase

@Suppress("LeakingThis")
@SuppressLint("ViewConstructor")
internal open class BeagleFlexView(
private val rootView: RootView,
Expand All @@ -39,6 +41,10 @@ internal open class BeagleFlexView(
private val viewModel: ScreenContextViewModel = rootView.generateViewModelInstance()
) : YogaLayout(rootView.getContext(), flexMapper.makeYogaNode(style)) {

init {
observeStyleChanges(style, this, yogaNode)
}

constructor(
rootView: RootView,
flexMapper: FlexMapper = FlexMapper()
Expand All @@ -47,8 +53,7 @@ internal open class BeagleFlexView(
var listenerOnViewDetachedFromWindow: (() -> Unit)? = null

fun addView(child: View, style: Style) {

super.addView(child, flexMapper.makeYogaNode(style))
addViewWithBind(style, child, this)
}

fun addServerDrivenComponent(serverDrivenComponent: ServerDrivenComponent,
Expand All @@ -65,7 +70,17 @@ internal open class BeagleFlexView(
(yogaNode as YogaNodeJNIBase).dirtyAllDescendants()
}
}
super.addView(view, flexMapper.makeYogaNode(style))
addViewWithBind(style, view, view)
}

private fun addViewWithBind(style: Style, child: View, viewBind: View){
val childYogaNode = flexMapper.makeYogaNode(style)
observeStyleChanges(style, viewBind, childYogaNode)
super.addView(child, childYogaNode)
}

private fun observeStyleChanges(style: Style, view: View, yogaNode: YogaNode) {
flexMapper.observeBindChangesFlex(style, rootView, view, yogaNode)
}

override fun onAttachedToWindow() {
Expand Down
3 changes: 2 additions & 1 deletion android/beagle/src/main/java/br/com/zup/beagle/core/Style.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package br.com.zup.beagle.core

import br.com.zup.beagle.android.context.Bind
import br.com.zup.beagle.widget.core.EdgeValue
import br.com.zup.beagle.widget.core.Flex
import br.com.zup.beagle.widget.core.Size
Expand Down Expand Up @@ -59,7 +60,7 @@ data class Style (
val position: EdgeValue? = null,
val flex: Flex? = null,
val positionType: PositionType? = null,
val display: Display? = null
val display: Bind<Display>? = null
)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@

package br.com.zup.beagle.android.engine.mapper

import android.view.View
import br.com.zup.beagle.android.context.valueOf
import br.com.zup.beagle.android.extensions.once
import br.com.zup.beagle.android.utils.Observer
import br.com.zup.beagle.android.utils.dp
import br.com.zup.beagle.android.utils.internalObserveBindChanges
import br.com.zup.beagle.android.widget.RootView
import br.com.zup.beagle.core.Display
import br.com.zup.beagle.core.Style
import br.com.zup.beagle.widget.core.AlignContent
Expand All @@ -40,12 +45,16 @@ import com.facebook.yoga.YogaNode
import com.facebook.yoga.YogaWrap
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.clearStaticMockk
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.slot
import io.mockk.unmockkAll
import io.mockk.verify
import io.mockk.verifyOrder
import io.mockk.verifySequence
import kotlin.test.assertFalse
import org.junit.After
import org.junit.Before
import org.junit.Test
Expand All @@ -55,8 +64,11 @@ private const val ONE_UNIT_VALUE = 1.0

class FlexMapperTest {

@MockK
private lateinit var yogaNode: YogaNode
private val yogaNodeMock: YogaNode = mockk(relaxed = true, relaxUnitFun = true)
private val rootViewMock: RootView = mockk()
private val viewMock: View = mockk(relaxUnitFun = true, relaxed = true)

private val observeSlot = slot<Observer<Display?>>()

private lateinit var flexMapper: FlexMapper

Expand All @@ -68,48 +80,25 @@ class FlexMapperTest {

mockkStatic(YogaNode::class)
mockkStatic("br.com.zup.beagle.android.utils.NumberExtensionsKt")
mockkStatic("br.com.zup.beagle.android.utils.WidgetExtensionsKt")

every {
internalObserveBindChanges(
rootView = rootViewMock,
view = viewMock,
bind = any(),
observes = capture(observeSlot)
)
} just Runs

every { HUNDRED_UNIT_VALUE.dp() } returns HUNDRED_UNIT_VALUE
every { ONE_UNIT_VALUE.dp() } returns ONE_UNIT_VALUE
every { YogaNode.create() } returns yogaNode
every { yogaNode.flexDirection = any() } just Runs
every { yogaNode.wrap = any() } just Runs
every { yogaNode.justifyContent = any() } just Runs
every { yogaNode.alignItems = any() } just Runs
every { yogaNode.alignSelf = any() } just Runs
every { yogaNode.alignContent = any() } just Runs
every { yogaNode.flex = any() } just Runs
every { yogaNode.flexGrow = any() } just Runs
every { yogaNode.flexShrink = any() } just Runs
every { yogaNode.display = any() } just Runs
every { yogaNode.aspectRatio = any() } just Runs
every { yogaNode.positionType = any() } just Runs
every { yogaNode.setWidth(any()) } just Runs
every { yogaNode.setWidthPercent(any()) } just Runs
every { yogaNode.setHeight(any()) } just Runs
every { yogaNode.setHeightPercent(any()) } just Runs
every { yogaNode.setMaxWidth(any()) } just Runs
every { yogaNode.setMaxWidthPercent(any()) } just Runs
every { yogaNode.setMaxHeight(any()) } just Runs
every { yogaNode.setMaxHeightPercent(any()) } just Runs
every { yogaNode.setMinWidth(any()) } just Runs
every { yogaNode.setMinWidthPercent(any()) } just Runs
every { yogaNode.setMinHeight(any()) } just Runs
every { yogaNode.setMinHeightPercent(any()) } just Runs
every { yogaNode.setFlexBasis(any()) } just Runs
every { yogaNode.setFlexBasisPercent(any()) } just Runs
every { yogaNode.setMargin(any(), any()) } just Runs
every { yogaNode.setMarginPercent(any(), any()) } just Runs
every { yogaNode.setPadding(any(), any()) } just Runs
every { yogaNode.setPaddingPercent(any(), any()) } just Runs
every { yogaNode.setPosition(any(), any()) } just Runs
every { yogaNode.setPositionPercent(any(), any()) } just Runs
every { yogaNode.setFlexBasisAuto() } just Runs
every { YogaNode.create() } returns yogaNodeMock
}

@After
fun tearDown() {
clearStaticMockk()
unmockkAll()
}

@Test
Expand Down Expand Up @@ -197,7 +186,7 @@ class FlexMapperTest {
}

@Test
fun makeYogaNode_should_set_flex_as_1(){
fun makeYogaNode_should_set_flex_as_1() {
//Given
val flex = Flex(
flex = ONE_UNIT_VALUE
Expand All @@ -207,7 +196,7 @@ class FlexMapperTest {
val yogaNode = flexMapper.makeYogaNode(Style(flex = flex))

//Then
verify (exactly = once()) { yogaNode.flex = ONE_UNIT_VALUE.toFloat() }
verify(exactly = once()) { yogaNode.flex = ONE_UNIT_VALUE.toFloat() }
}

@Test
Expand Down Expand Up @@ -239,31 +228,53 @@ class FlexMapperTest {
}

@Test
fun makeYogaNode_should_set_display_as_FLEX() {
fun `GIVEN display NONE WHEN call observe bind changes THEN it should set in yoga node correct display`() {
// Given
val style = Style(
display = Display.FLEX
display = valueOf(Display.NONE)
)

// When
val yogaNode = flexMapper.makeYogaNode(style)
flexMapper.observeBindChangesFlex(style, rootViewMock, viewMock, yogaNodeMock)
observeSlot.captured.invoke(Display.NONE)

// Then
verify(exactly = once()) { yogaNode.display = YogaDisplay.FLEX }
verifyOrder {
yogaNodeMock.display = YogaDisplay.NONE
viewMock.requestLayout()
}
}

@Test
fun makeYogaNode_should_set_display_as_NONE() {
fun `GIVEN display FLEX WHEN call observe bind changes THEN it should set in yoga node correct display`() {
// Given
val style = Style(
display = Display.NONE
display = valueOf(Display.FLEX)
)

// When
val yogaNode = flexMapper.makeYogaNode(style)
flexMapper.observeBindChangesFlex(style, rootViewMock, viewMock, yogaNodeMock)
observeSlot.captured.invoke(Display.FLEX)

// Then
verifyOrder {
yogaNodeMock.display = YogaDisplay.FLEX
viewMock.requestLayout()
}
}

@Test
fun `GIVEN display NULL WHEN call observe bind changes THEN it should never call bind changes`() {
// Given
val style = Style(
display = null
)

// When
flexMapper.observeBindChangesFlex(style, rootViewMock, viewMock, yogaNodeMock)

// Then
verify(exactly = once()) { yogaNode.display = YogaDisplay.NONE }
assertFalse(observeSlot.isCaptured)
}

@Test
Expand Down
Loading