data class Model(
val count: Int
)
sealed class Msg {
}
Slide 53
Slide 53 text
data class Model(
val count: Int
)
sealed class Msg {
object Increment : Msg()
}
Slide 54
Slide 54 text
data class Model(
val count: Int
)
sealed class Msg {
object Increment : Msg()
object Decrement : Msg()
}
Slide 55
Slide 55 text
data class Model(
val count: Int
)
sealed class Msg {
object Increment : Msg()
object Decrement : Msg()
}
data class Props(
)
Slide 56
Slide 56 text
data class Model(
val count: Int
)
sealed class Msg {
object Increment : Msg()
object Decrement : Msg()
}
data class Props(
val count: Int,
)
Slide 57
Slide 57 text
data class Model(
val count: Int
)
sealed class Msg {
object Increment : Msg()
object Decrement : Msg()
}
data class Props(
val count: Int,
val increment: (Dispatch) -> Unit,
)
Slide 58
Slide 58 text
data class Model(
val count: Int
)
sealed class Msg {
object Increment : Msg()
object Decrement : Msg()
}
data class Props(
val count: Int,
val increment: (Dispatch) -> Unit,
val decrement: (Dispatch) -> Unit,
)
Slide 59
Slide 59 text
typealias Dispatch
Slide 60
Slide 60 text
typealias Dispatch = (Msg) -> Unit
Slide 61
Slide 61 text
No content
Slide 62
Slide 62 text
No content
Slide 63
Slide 63 text
val init: () -> Pair> =
{ }
Slide 64
Slide 64 text
val init: () -> Pair> =
{ Model(count = 0) }
Slide 65
Slide 65 text
val init: () -> Pair> =
{ Model(count = 0) to none() }
Slide 66
Slide 66 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
}
Slide 67
Slide 67 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
when (msg) {
}
}
Slide 68
Slide 68 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
when (msg) {
Increment ->
}
}
Slide 69
Slide 69 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
when (msg) {
Increment -> model.copy(count = model.count + 1)
}
}
Slide 70
Slide 70 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
when (msg) {
Increment -> model.copy(count = model.count + 1)
Decrement ->
}
}
Slide 71
Slide 71 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
when (msg) {
Increment -> model.copy(count = model.count + 1)
Decrement -> model.copy(count = model.count - 1)
}
}
Slide 72
Slide 72 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
when (msg) {
Increment -> model.copy(count = model.count + 1)
Decrement -> model.copy(count = model.count - 1)
} to none()
}
Slide 73
Slide 73 text
val view: (Model) -> Props =
{ model ->
}
Slide 74
Slide 74 text
val view: (Model) -> Props =
{ model ->
Props(
)
}
Slide 75
Slide 75 text
val view: (Model) -> Props =
{ model ->
Props(
count = model.count,
)
}
@Test
fun `initial Model count should be 0`() {
val expected = Model(count = 0)
}
Slide 94
Slide 94 text
@Test
fun `initial Model count should be 0`() {
val expected = Model(count = 0)
val (actual, _) = init()
}
Slide 95
Slide 95 text
@Test
fun `initial Model count should be 0`() {
val expected = Model(count = 0)
val (actual, _) = init()
assertEquals(expected, actual)
}
Slide 96
Slide 96 text
@Test
fun `Increment msg should increment Model count`() {
}
Slide 97
Slide 97 text
@Test
fun `Increment msg should increment Model count`() {
val msg = Msg.Increment
val model = Model(count = 0)
val expected = Model(count = 1)
}
Slide 98
Slide 98 text
@Test
fun `Increment msg should increment Model count`() {
val msg = Msg.Increment
val model = Model(count = 0)
val expected = Model(count = 1)
val (actual, _) = update(msg, model)
}
Slide 99
Slide 99 text
@Test
fun `Increment msg should increment Model count`() {
val msg = Msg.Increment
val model = Model(count = 0)
val expected = Model(count = 1)
val (actual, _) = update(msg, model)
assertEquals(expected, actual)
}
Slide 100
Slide 100 text
@Test
fun `Decrement msg should increment Model count`() {
}
Slide 101
Slide 101 text
@Test
fun `Decrement msg should increment Model count`() {
val msg = Msg.Decrement
val model = Model(count = 0)
val expected = Model(count = -1)
}
Slide 102
Slide 102 text
@Test
fun `Decrement msg should increment Model count`() {
val msg = Msg.Decrement
val model = Model(count = 0)
val expected = Model(count = -1)
val (actual, _) = update(msg, model)
}
Slide 103
Slide 103 text
@Test
fun `Decrement msg should increment Model count`() {
val msg = Msg.Decrement
val model = Model(count = 0)
val expected = Model(count = -1)
val (actual, _) = update(msg, model)
assertEquals(expected, actual)
}
Slide 104
Slide 104 text
@Test
fun `Props count should be equal to Model count`() {
}
Slide 105
Slide 105 text
@Test
fun `Props count should be equal to Model count`() {
val model = Model(count = 0)
val expected = model.count
}
Slide 106
Slide 106 text
@Test
fun `Props count should be equal to Model count`() {
val model = Model(count = 0)
val expected = model.count
val props = view(model)
val actual = props.count
}
Slide 107
Slide 107 text
@Test
fun `Props count should be equal to Model count`() {
val model = Model(count = 0)
val expected = model.count
val props = view(model)
val actual = props.count
assertEquals(expected, actual)
}
Slide 108
Slide 108 text
@Test
fun `Props increment should dispatch Increment msg`() {
}
Slide 109
Slide 109 text
@Test
fun `Props increment should dispatch Increment msg`() {
val model = Model(count = 0)
val props = view(model)
}
Slide 110
Slide 110 text
@Test
fun `Props increment should dispatch Increment msg`() {
val model = Model(count = 0)
val props = view(model)
props.increment { msg ->
}
}
Slide 111
Slide 111 text
@Test
fun `Props increment should dispatch Increment msg`() {
val model = Model(count = 0)
val props = view(model)
props.increment { msg ->
assertEquals(msg, Msg.Increment)
}
}
Slide 112
Slide 112 text
@Test
fun `Props decrement should dispatch Decrement msg`() {
}
Slide 113
Slide 113 text
@Test
fun `Props decrement should dispatch Decrement msg`() {
val model = Model(count = 0)
val props = view(model)
}
Slide 114
Slide 114 text
@Test
fun `Props decrement should dispatch Decrement msg`() {
val model = Model(count = 0)
val props = view(model)
props.decrement { msg ->
}
}
Slide 115
Slide 115 text
@Test
fun `Props decrement should dispatch Decrement msg`() {
val model = Model(count = 0)
val props = view(model)
props.decrement { msg ->
assertEquals(msg, Msg.Decrement)
}
}
Slide 116
Slide 116 text
Boundaries
Slide 117
Slide 117 text
typealias GetCount
Slide 118
Slide 118 text
typealias GetCount = () -> Int
Slide 119
Slide 119 text
typealias GetCount = () -> Int
typealias PutCount
Slide 120
Slide 120 text
typealias GetCount = () -> Int
typealias PutCount = (Int) -> Unit
Slide 121
Slide 121 text
class CounterService(context: Context) {
}
Slide 122
Slide 122 text
class CounterService(context: Context) {
private val prefs =
context.getSharedPreferences("counter", MODE_PRIVATE)
}
Slide 123
Slide 123 text
class CounterService(context: Context) {
private val prefs =
context.getSharedPreferences("counter", MODE_PRIVATE)
val getCount: GetCount = { }
}
Slide 124
Slide 124 text
class CounterService(context: Context) {
private val prefs =
context.getSharedPreferences("counter", MODE_PRIVATE)
val getCount: GetCount = { prefs.getInt("count", 0) }
}
Slide 125
Slide 125 text
class CounterService(context: Context) {
private val prefs =
context.getSharedPreferences("counter", MODE_PRIVATE)
val getCount: GetCount = { prefs.getInt("count", 0) }
val putCount: PutCount =
{ count ->
}
}
Slide 126
Slide 126 text
class CounterService(context: Context) {
private val prefs =
context.getSharedPreferences("counter", MODE_PRIVATE)
val getCount: GetCount = { prefs.getInt("count", 0) }
val putCount: PutCount =
{ count ->
prefs.edit().putInt("count", count).apply()
}
}
Slide 127
Slide 127 text
{ }
{ count -> }
// typealias GetCount = () -> Int
// typealias PutCount = (Int) -> Unit
val getCount: GetCount =
val putCount: PutCount =
@Test
fun `initial Effect should dispatch SetCount`() {
}
Slide 164
Slide 164 text
@Test
fun `initial Effect should dispatch SetCount`() {
val getCount: GetCount = { 0 }
val expected = Msg.SetCount(getCount())
val (_, effect) = init()
}
Slide 165
Slide 165 text
@Test
fun `initial Effect should dispatch SetCount`() {
val getCount: GetCount = { 0 }
val expected = Msg.SetCount(getCount())
val (_, effect) = init()
runBlocking {
effect { actual ->
}
}
}
Slide 166
Slide 166 text
@Test
fun `initial Effect should dispatch SetCount`() {
val getCount: GetCount = { 0 }
val expected = Msg.SetCount(getCount())
val (_, effect) = init()
runBlocking {
effect { actual ->
assertEquals(expected, actual)
}
}
}
Slide 167
Slide 167 text
@Test
fun `update effect should put count`() {
}
Slide 168
Slide 168 text
@Test
fun `update effect should put count`() {
val msg = Msg.SetCount(count = 42)
val model = Model(count = 0)
val putCount: PutCount = { count ->
}
}
Slide 169
Slide 169 text
@Test
fun `update effect should put count`() {
val msg = Msg.SetCount(count = 42)
val model = Model(count = 0)
val putCount: PutCount = { count ->
}
val (_, effect) = update(putCount)(msg, model)
runBlocking { effect { } }
}
Slide 170
Slide 170 text
@Test
fun `update effect should put count`() {
val msg = Msg.SetCount(count = 42)
val model = Model(count = 0)
val putCount: PutCount = { count ->
assertEquals(count, msg.count)
}
val (_, effect) = update(putCount)(msg, model)
runBlocking { effect { } }
}
Slide 171
Slide 171 text
Composition
Slide 172
Slide 172 text
No content
Slide 173
Slide 173 text
object Child {
}
Slide 174
Slide 174 text
object Child {
class Model
}
Slide 175
Slide 175 text
object Child {
class Model
class Msg
}
Slide 176
Slide 176 text
object Child {
class Model
class Msg
class Props
}
Slide 177
Slide 177 text
object Child {
class Model
class Msg
class Props
val init: () -> Pair> = ...
}
Slide 178
Slide 178 text
object Child {
class Model
class Msg
class Props
val init: () -> Pair> = ...
val update: (Msg, Model) -> Pair> = ...
}
Slide 179
Slide 179 text
object Child {
class Model
class Msg
class Props
val init: () -> Pair> = ...
val update: (Msg, Model) -> Pair> = ...
val view: (Model) -> Props = ...
}
Slide 180
Slide 180 text
object Child {
class Model
class Msg
class Props
val init: () -> Pair> = ...
val update: (Msg, Model) -> Pair> = ...
val view: (Model) -> Props = ...
}
Slide 181
Slide 181 text
object Parent {
class.Model
class Msg
class Props
val init: () -> Pair> = ...
val update: (Msg, Model).-> Pair> = ...
val view: (Model).-> Props = ...
}
Slide 182
Slide 182 text
class Model(
val child: Child.Model
)
Slide 183
Slide 183 text
sealed class Msg {
class ChildMsg(
val child: Child.Msg
) : Msg()
}
Slide 184
Slide 184 text
class Props(
val child: Child.Props
)
Slide 185
Slide 185 text
val init: () -> Pair> =
{
// Child.init()
}
Slide 186
Slide 186 text
val update: (Msg, Model) -> Pair> =
{ msg, model ->
// Child.update()
}
Slide 187
Slide 187 text
val view: (Model) -> Props =
{ model ->
// Child.view()
}
Slide 188
Slide 188 text
data class Model(
)
Slide 189
Slide 189 text
data class Model(
val counters: Map
)
Slide 190
Slide 190 text
sealed class Msg {
}
Slide 191
Slide 191 text
sealed class Msg {
class SetCounts(val counts: Map) : Msg()
object AddCounter : Msg()
class RemoveCounter(val id: Id) : Msg()
class CounterMsg(
val id: Id,
val msg: Counter.Msg
) : Msg()
}
Slide 192
Slide 192 text
class Props(
)
Slide 193
Slide 193 text
class Props(
val counters: List,
val addCounter: (Dispatch) -> Unit,
)
Slide 194
Slide 194 text
class Props(
val counters: List,
val addCounter: (Dispatch) -> Unit,
) {
class CounterRow(
)
}
Slide 195
Slide 195 text
class Props(
val counters: List,
val addCounter: (Dispatch) -> Unit,
) {
class CounterRow(
val props: Counter.Props,
val removeCounter: (Dispatch) -> Unit,
)
}
Slide 196
Slide 196 text
github.com/pardom/mfa-with-oolong
Slide 197
Slide 197 text
What Have
We Learned?
Slide 198
Slide 198 text
Purity
Slide 199
Slide 199 text
Purity
Boundaries
Slide 200
Slide 200 text
Purity
Boundaries
Composition
Slide 201
Slide 201 text
Architecture Patterns are
architecture style + context.