diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml
index 049ea049..62fad4de 100644
--- a/.github/workflows/build_and_test.yml
+++ b/.github/workflows/build_and_test.yml
@@ -19,4 +19,4 @@ jobs:
run: ./gradlew test
- name: Build Project
- run: ./gradlew assemble
\ No newline at end of file
+ run: ./gradlew assemble
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index b86273d9..b589d56e 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 6c39a4ff..13e76d17 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/cancellation/1_cancellation.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/cancellation/1_cancellation.kt
deleted file mode 100644
index 0e6e57d4..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/cancellation/1_cancellation.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.cancellation
-
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
-
- val job = launch {
- repeat(10) { index ->
- println("operation number $index")
- try {
- delay(100)
- } catch (exception: CancellationException) {
- println("CancellationException was thrown")
- throw CancellationException()
- }
- }
- }
-
- delay(250)
- println("Cancelling Coroutine")
- job.cancel()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/cancellation/2_cooperative_cancellation.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/cancellation/2_cooperative_cancellation.kt
deleted file mode 100644
index 78931a57..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/cancellation/2_cooperative_cancellation.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.cancellation
-
-import kotlinx.coroutines.*
-
-fun main() = runBlocking {
-
- val job = launch(Dispatchers.Default) {
- repeat(10) { index ->
- if (isActive) {
- println("operation number $index")
- Thread.sleep(100)
- } else {
- // perform some cleanup on cancellation
- withContext(NonCancellable) {
- delay(100)
- println("Clean up done!")
- }
- throw CancellationException()
- }
- }
- }
-
- delay(250)
- println("Cancelling Coroutine")
- job.cancel()
-
- val globalCoroutineJob = GlobalScope.launch {
- repeat(10) {
- println("$it")
- delay(100)
- }
- }
- delay(250)
- globalCoroutineJob.cancel()
- delay(1000)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/coroutinebuilders/1_launch.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/coroutinebuilders/1_launch.kt
deleted file mode 100644
index 1df4db87..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/coroutinebuilders/1_launch.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.coroutinebuilders
-
-import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
- val job = launch(start = CoroutineStart.LAZY) {
- networkRequest()
- println("result received")
- }
- delay(200)
- job.start()
- println("end of runBlocking")
-}
-
-suspend fun networkRequest(): String {
- delay(500)
- return "Result"
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/coroutinebuilders/2_async.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/coroutinebuilders/2_async.kt
deleted file mode 100644
index 2fa73867..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/coroutinebuilders/2_async.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.coroutinebuilders
-
-import kotlinx.coroutines.async
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
-
- val startTime = System.currentTimeMillis()
-
- val deferred1 = async {
- val result1 = networkCall(1).also {
- println("result received: $it after ${elapsedMillis(startTime)}ms")
- }
- result1
- }
-
- val deferred2 = async {
- val result2 = networkCall(2)
- println("result received: $result2 after ${elapsedMillis(startTime)}ms")
- result2
- }
-
- val resultList = listOf(deferred1.await(), deferred2.await())
-
- println("Result list: $resultList after ${elapsedMillis(startTime)}ms")
-}
-
-suspend fun networkCall(number: Int): String {
- delay(500)
- return "Result $number"
-}
-
-fun elapsedMillis(startTime: Long) = System.currentTimeMillis() - startTime
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/1_try_catch.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/1_try_catch.kt
deleted file mode 100644
index 3b13535a..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/1_try_catch.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.exceptionhandling
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-
-fun main() {
-
- val scope = CoroutineScope(Job())
- try {
- scope.launch {
- functionThatThrowsIt()
- }
- } catch (e: Exception) {
- println("Caught: $e")
- }
-
- Thread.sleep(100)
-}
-
-fun functionThatThrowsIt() {
- throw RuntimeException()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/2_coroutine_exception_handler.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/2_coroutine_exception_handler.kt
deleted file mode 100644
index 0967f338..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/2_coroutine_exception_handler.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.exceptionhandling
-
-import kotlinx.coroutines.CoroutineExceptionHandler
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-
-fun main() {
-
- val exceptionHandler = CoroutineExceptionHandler { context, exception ->
- println("Caught $exception in CoroutineExceptionHandler")
- }
-
- val scope = CoroutineScope(Job())
-
- scope.launch {
- launch(exceptionHandler) {
- functionThatThrowsIt()
- }
- }
-
- Thread.sleep(100)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/3_try_catch_vs_exception_handler.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/3_try_catch_vs_exception_handler.kt
deleted file mode 100644
index 961ba9b4..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/3_try_catch_vs_exception_handler.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.exceptionhandling
-
-import kotlinx.coroutines.*
-
-fun main() {
-
- val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
- println("Caught exception: $throwable")
- }
-
- val scope = CoroutineScope(Job())
-
- scope.launch(exceptionHandler) {
- launch {
- println("Starting coroutine 1")
- delay(100)
- throw RuntimeException()
- }
- launch {
- println("Starting coroutine 2")
- delay(3000)
- println("Coroutine 2 completed")
- }
- }
-
- Thread.sleep(5000)
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/4_launch_and_async.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/4_launch_and_async.kt
deleted file mode 100644
index fc613fb5..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/4_launch_and_async.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.exceptionhandling
-
-import kotlinx.coroutines.*
-
-fun main() {
-
- val exceptionHandler = CoroutineExceptionHandler { context, exception ->
- println("Caught $exception in CoroutineExceptionHandler")
- }
-
- val scope = CoroutineScope(Job() + exceptionHandler)
-
- scope.async {
- val deferred = async {
- delay(200)
- throw RuntimeException()
- }
- }
-
- Thread.sleep(1000)
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/5_exception_handling_specifics_coroutineScope.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/5_exception_handling_specifics_coroutineScope.kt
deleted file mode 100644
index 6551fe7b..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/5_exception_handling_specifics_coroutineScope.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-
-
-fun main() = runBlocking() {
-
- try {
- doSomeThingSuspend()
- } catch (e: Exception) {
- println("Caught $e")
- }
-
-}
-
-private suspend fun doSomeThingSuspend() {
- coroutineScope {
- launch {
- throw RuntimeException()
- }
- }
-}
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/6_exception_handling_specifics_supervisorScope.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/6_exception_handling_specifics_supervisorScope.kt
deleted file mode 100644
index d36fb9bc..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/exceptionhandling/6_exception_handling_specifics_supervisorScope.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.exceptionhandling
-
-import kotlinx.coroutines.*
-
-fun main() {
-
- val ceh = CoroutineExceptionHandler { coroutineContext, throwable ->
- println("Caught $throwable in CoroutineExceptionHandler")
- }
-
- val scope = CoroutineScope(Job())
-
- scope.launch(ceh) {
- try {
- supervisorScope {
- launch {
- println("CEH: ${coroutineContext[CoroutineExceptionHandler]}")
- throw RuntimeException()
- }
- }
- } catch (e: Exception) {
- println("Caught $e")
- }
- }
-
- Thread.sleep(100)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/1-returning-single-item.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/1-returning-single-item.kt
deleted file mode 100644
index 39d1f667..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/1-returning-single-item.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.basics
-
-import java.math.BigInteger
-
-fun main() {
- val result = calculateFactorialOf(5)
- println("Result: $result")
-}
-
-// factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
-private fun calculateFactorialOf(number: Int): BigInteger {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
- Thread.sleep(10)
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- }
- return factorial
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/2-return-list.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/2-return-list.kt
deleted file mode 100644
index d9c5e31b..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/2-return-list.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.basics
-
-import com.lukaslechner.coroutineusecasesonandroid.playground.utils.printWithTimePassed
-import java.math.BigInteger
-
-fun main() {
- val startTime = System.currentTimeMillis()
- calculateFactorialOf(5).forEach {
- printWithTimePassed(it,startTime)
- }
-}
-
-// factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
-private fun calculateFactorialOf(number: Int): List = buildList {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
- Thread.sleep(10)
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- add(factorial)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/3-sequences.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/3-sequences.kt
deleted file mode 100644
index 092d1bc5..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/3-sequences.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.basics
-
-import com.lukaslechner.coroutineusecasesonandroid.playground.utils.printWithTimePassed
-import java.math.BigInteger
-
-fun main() {
- val startTime = System.currentTimeMillis()
- calculateFactorialOf(5).forEach {
- printWithTimePassed(it,startTime)
- }
- println("Ready for more work!")
-}
-
-// factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
-private fun calculateFactorialOf(number: Int): Sequence = sequence {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
- Thread.sleep(10)
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- yield(factorial)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/4-flow.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/4-flow.kt
deleted file mode 100644
index 05ee970c..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/basics/4-flow.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.basics
-
-import com.lukaslechner.coroutineusecasesonandroid.playground.utils.printWithTimePassed
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import java.math.BigInteger
-
-fun main() = runBlocking {
- val startTime = System.currentTimeMillis()
-
- launch {
- calculateFactorialOf(5).collect {
- printWithTimePassed(it, startTime)
- }
- }
-
- println("Ready for more work!")
-}
-
-// factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
-private fun calculateFactorialOf(number: Int): Flow = flow {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
- delay(10)
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- emit(factorial)
- }
-}.flowOn(Dispatchers.Default)
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/builders/1_basic_flow_builders.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/builders/1_basic_flow_builders.kt
deleted file mode 100644
index 6d5b64a5..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/builders/1_basic_flow_builders.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.builders
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.asFlow
-import kotlinx.coroutines.flow.emitAll
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.flowOf
-
-suspend fun main() {
-
- val firstFlow = flowOf(1).collect { emittedValue ->
- println("firstFlow: $emittedValue")
- }
-
- val secondFlow = flowOf(1, 2, 3)
-
- secondFlow.collect { emittedValue ->
- println("secondFlow: $emittedValue")
- }
-
- listOf("A", "B", "C").asFlow().collect { emittedValue ->
- println("asFlow: $emittedValue")
- }
-
- flow {
- delay(2000)
- emit("item emitted after 2000ms")
-
- emitAll(secondFlow)
- }.collect { emittedValue ->
- println("flow{}: $emittedValue")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/1_cancellation_basics.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/1_cancellation_basics.kt
deleted file mode 100644
index 6c03e774..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/1_cancellation_basics.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.cancellation
-
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.launch
-import kotlin.coroutines.EmptyCoroutineContext
-
-suspend fun main() {
- val scope = CoroutineScope(EmptyCoroutineContext)
-
- scope.launch {
- intFlow()
- .onCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Flow got cancelled.")
- }
- }
- .collect {
- println("Collected $it")
-
- if (it == 2) {
- cancel()
- }
- }
- }.join()
-}
-
-private fun intFlow() = flow {
- emit(1)
- emit(2)
- emit(3)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/2_cooperative_cancellation_in_flows.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/2_cooperative_cancellation_in_flows.kt
deleted file mode 100644
index 75c4cdcc..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/2_cooperative_cancellation_in_flows.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.cancellation
-
-import kotlinx.coroutines.*
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.onCompletion
-import java.math.BigInteger
-import kotlin.coroutines.EmptyCoroutineContext
-
-suspend fun main() {
- val scope = CoroutineScope(EmptyCoroutineContext)
-
- scope.launch {
- intFlow()
- .onCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Flow got cancelled.")
- }
- }
- .collect {
- println("Collected $it")
-
- if (it == 2) {
- cancel()
- }
- }
- }.join()
-}
-
-private fun intFlow() = flow {
- emit(1)
- emit(2)
-
- println("Start calculation")
- calculateFactorialOf(1_000)
- println("Calculation finished!")
-
- emit(3)
-}
-
-private suspend fun calculateFactorialOf(number: Int): BigInteger = coroutineScope {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- ensureActive()
- }
- factorial
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/3_cancellable_operator.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/3_cancellable_operator.kt
deleted file mode 100644
index cd3194a5..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/cancellation/3_cancellable_operator.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.cancellation
-
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.cancellable
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.launch
-import kotlin.coroutines.EmptyCoroutineContext
-
-suspend fun main() {
- val scope = CoroutineScope(EmptyCoroutineContext)
-
- scope.launch {
- flowOf(1, 2, 3)
- .onCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Flow got cancelled.")
- }
- }.cancellable()
- .collect {
- println("Collected $it")
-
- if (it == 2) {
- cancel()
- }
- }
- }.join()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/1_sending_single_value.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/1_sending_single_value.kt
deleted file mode 100644
index cef8c7c4..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/1_sending_single_value.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.channels
-
-import kotlinx.coroutines.async
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- val deferred = async {
- delay(100) // some computation
- 10
- }
-
- launch {
- val result = deferred.await()
- println(result)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/2_sending_multiple_values.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/2_sending_multiple_values.kt
deleted file mode 100644
index f0d9d514..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/2_sending_multiple_values.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.channels
-
-import kotlinx.coroutines.channels.consumeEach
-import kotlinx.coroutines.channels.produce
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- val channel = produce {
- println("Sending 10")
- send(10)
-
- println("Sending 20")
- send(20)
- }
-
- launch {
- channel.consumeEach { receivedValue ->
- println("Consumer1: $receivedValue")
- }
- }
-
- launch {
- channel.consumeEach { receivedValue ->
- println("Consumer2: $receivedValue")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/3_drop_while_busy.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/3_drop_while_busy.kt
deleted file mode 100644
index 2daa818d..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/channels/3_drop_while_busy.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.channels
-
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.consumeEach
-import kotlinx.coroutines.channels.produce
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.consumeAsFlow
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.launch
-
-/**
- UseCase: We want to trigger some processing. While the downstream is currently
- busy, we want to drop the current trigger emission.
-
- With a SharedFlow, this is not possible, since we need to define a buffer size of
- > 0 for buffer strategies like "DROP_LATEST". Channels however have a buffer sice of 0
- by default.
-
- Another option is to use the custom operator "dropIfBusy" (see below)
-
- See also: https://stackoverflow.com/questions/64844821/how-to-drop-latest-with-coroutine-flowt/74560222#74560222
-**/
-
-fun Flow.dropIfBusy(): Flow = flow {
- coroutineScope {
- val channel = produce {
- collect { trySend(it) }
- }
- channel.consumeEach { emit(it) }
- }
-}
-
-suspend fun main(): Unit = coroutineScope {
-
- val channel = Channel()
-
- launch {
- channel
- .consumeAsFlow()
- .collect {
- println("Process $it")
- delay(1000)
- println("$it processed")
- }
- }
-
- launch {
-
- delay(100)
-
- // 1 should be processed
- channel.trySend(1)
- println("sharedFlow emits 1")
-
- // 2 should not be processed since downstream is busy
- channel.trySend(2)
- println("sharedFlow emits 2")
-
- // 3 should be processed again
- delay(2000)
- channel.trySend(3)
- println("sharedFlow emits 3")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/10_buffer_in_stateflow.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/10_buffer_in_stateflow.kt
deleted file mode 100644
index 45a01edd..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/10_buffer_in_stateflow.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.launch
-import kotlin.system.measureTimeMillis
-
-suspend fun main(): Unit = coroutineScope {
-
- val flow = MutableStateFlow(0)
-
- // Collector 1
- launch {
- flow.collect {
- println("Collector 1 processes $it")
- }
- }
-
- // Collector 2
- launch {
- flow.collect {
- println("Collector 2 processes $it")
- delay(100)
- }
- }
-
- // Emitter
- launch {
- val timeToEmit = measureTimeMillis {
- repeat(5) {
- flow.emit(it)
- delay(10)
- }
- }
- println("Time to emit all values: $timeToEmit ms")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/1_buffer.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/1_buffer.kt
deleted file mode 100644
index 6b289951..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/1_buffer.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.buffer
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- println("Emitter: Start Cooking Pancake $it")
- delay(100)
- println("Emitter: Pancake $it ready!")
- emit(it)
- }
- }.buffer()
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/2_buffer_overflow_suspend.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/2_buffer_overflow_suspend.kt
deleted file mode 100644
index acf09b91..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/2_buffer_overflow_suspend.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.channels.BufferOverflow
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.buffer
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- val pancakeIndex = it + 1
- println("Emitter: Start Cooking Pancake $pancakeIndex")
- delay(100)
- println("Emitter: Pancake $pancakeIndex ready!")
- emit(pancakeIndex)
- }
- }.buffer(capacity = 1, onBufferOverflow = BufferOverflow.SUSPEND)
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/3_buffer_overflow_drop_oldest.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/3_buffer_overflow_drop_oldest.kt
deleted file mode 100644
index 4ba6dc9a..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/3_buffer_overflow_drop_oldest.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.channels.BufferOverflow
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.buffer
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- val pancakeIndex = it + 1
- println("Emitter: Start Cooking Pancake $pancakeIndex")
- delay(100)
- println("Emitter: Pancake $pancakeIndex ready!")
- emit(pancakeIndex)
- }
- }.buffer(capacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/4_buffer_overflow_drop_latest.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/4_buffer_overflow_drop_latest.kt
deleted file mode 100644
index 1a1e0bb2..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/4_buffer_overflow_drop_latest.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.channels.BufferOverflow
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.buffer
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- val pancakeIndex = it + 1
- println("Emitter: Start Cooking Pancake $pancakeIndex")
- delay(100)
- println("Emitter: Pancake $pancakeIndex ready!")
- emit(pancakeIndex)
- }
- }.buffer(capacity = 1, onBufferOverflow = BufferOverflow.DROP_LATEST)
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/5_buffer_unlimited_size.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/5_buffer_unlimited_size.kt
deleted file mode 100644
index eed81320..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/5_buffer_unlimited_size.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.buffer
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- val pancakeIndex = it + 1
- println("Emitter: Start Cooking Pancake $pancakeIndex")
- delay(100)
- println("Emitter: Pancake $pancakeIndex ready!")
- emit(pancakeIndex)
- }
- }.buffer(capacity = UNLIMITED)
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/6_collect_latest.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/6_collect_latest.kt
deleted file mode 100644
index abbd0424..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/6_collect_latest.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.collectLatest
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- val pancakeIndex = it + 1
- println("Emitter: Start Cooking Pancake $pancakeIndex")
- delay(100)
- println("Emitter: Pancake $pancakeIndex ready!")
- emit(pancakeIndex)
- }
- }
-
- flow.collectLatest {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/7_map_latest.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/7_map_latest.kt
deleted file mode 100644
index 4a73326c..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/7_map_latest.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.mapLatest
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- val pancakeIndex = it + 1
- println("Emitter: Start Cooking Pancake $pancakeIndex")
- delay(100)
- println("Emitter: Pancake $pancakeIndex ready!")
- emit(pancakeIndex)
- }
- }.mapLatest {
- println("Add topping onto the pancake $it")
- delay(200)
- it
- }
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/8_conflate.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/8_conflate.kt
deleted file mode 100644
index d3b4811d..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/8_conflate.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.conflate
-import kotlinx.coroutines.flow.flow
-
-suspend fun main() = coroutineScope {
-
- val flow = flow {
- repeat(5) {
- println("Emitter: Start Cooking Pancake $it")
- delay(100)
- println("Emitter: Pancake $it ready!")
- emit(it)
- }
- }.conflate()
-
- flow.collect {
- println("Collector: Start eating pancake $it")
- delay(300)
- println("Collector: Finished eating pancake $it")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/9_buffer_in_sharedflow.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/9_buffer_in_sharedflow.kt
deleted file mode 100644
index 7a2a63c0..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/concurrency/9_buffer_in_sharedflow.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.concurrency
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.launch
-import kotlin.system.measureTimeMillis
-
-suspend fun main(): Unit = coroutineScope {
-
- val flow = MutableSharedFlow(extraBufferCapacity = 10)
-
- // Collector 1
- launch {
- flow.collect {
- println("Collector 1 processes $it")
- }
- }
-
- // Collector 2
- launch {
- flow.collect {
- println("Collector 2 processes $it")
- delay(100)
- }
- }
-
- // Emitter
- launch {
- val timeToEmit = measureTimeMillis {
- repeat(5) {
- flow.emit(it)
- delay(10)
- }
- }
- println("Time to emit all values: $timeToEmit ms")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/1_try-catch.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/1_try-catch.kt
deleted file mode 100644
index 9a03fe22..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/1_try-catch.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- launch {
- val stocksFlow = stocksFlow()
- .map {
- throw Exception("Exception in Map")
- }
-
- try {
- stocksFlow
- .onCompletion { cause ->
- if (cause == null) {
- println("Flow completed successfully!")
- } else {
- println("Flow completed exceptionally with $cause")
- }
- }
- .collect { stock ->
- println("Collected $stock")
- }
- } catch (e: Exception) {
- println("Handle Exception in catch block - $e")
- }
- }
-}
-
-private fun stocksFlow(): Flow = flow {
- emit("Apple")
- emit("Microsoft")
-
- throw Exception("Network Request Failed!")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/2_catch.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/2_catch.kt
deleted file mode 100644
index 9f6487f9..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/2_catch.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- launch {
- val stocksFlow = stocksFlow()
-
- stocksFlow
- .onCompletion { cause ->
- if (cause == null) {
- println("Flow completed successfully!")
- } else {
- println("Flow completed exceptionally with $cause")
- }
- }
- .catch { throwable ->
- println("Handle exception in catch() operator $throwable")
- }
- .collect { stock ->
- println("Collected $stock")
- }
- }
-}
-
-private fun stocksFlow(): Flow = flow {
- emit("Apple")
- emit("Microsoft")
-
- throw Exception("Network Request Failed!")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/3_emit_single_value.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/3_emit_single_value.kt
deleted file mode 100644
index c1db8d7d..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/3_emit_single_value.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- launch {
- val stocksFlow = stocksFlow()
-
- stocksFlow
- .onCompletion { cause ->
- if (cause == null) {
- println("Flow completed successfully!")
- } else {
- println("Flow completed exceptionally with $cause")
- }
- }
- .catch { throwable ->
- println("Handle exception in catch() operator $throwable")
- emit("Default Stock")
- }
- .collect { stock ->
- println("Collected $stock")
- }
- }
-}
-
-private fun stocksFlow(): Flow = flow {
- emit("Apple")
- emit("Microsoft")
-
- throw Exception("Network Request Failed!")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/4_fallback_flow.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/4_fallback_flow.kt
deleted file mode 100644
index a52980de..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/4_fallback_flow.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.*
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- launch {
- val stocksFlow = stocksFlow()
-
- stocksFlow
- .onCompletion { cause ->
- if (cause == null) {
- println("Flow completed successfully!")
- } else {
- println("Flow completed exceptionally with $cause")
- }
- }
- .catch { throwable ->
- println("Handle exception in catch() operator $throwable")
- emitAll(fallbackFlow())
- }.catch { throwable ->
- println("Handle exception in 2. catch() operator $throwable")
- }
- .collect { stock ->
- println("Collected $stock")
- }
- }
-}
-
-private fun stocksFlow(): Flow = flow {
- emit("Apple")
- emit("Microsoft")
-
- throw Exception("Network Request Failed!")
-}
-
-private fun fallbackFlow(): Flow = flow {
- emit("Fallback Stock")
-
- throw Exception("Exception in Fallback Flow")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/5_exception_in_collect.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/5_exception_in_collect.kt
deleted file mode 100644
index e2a88a40..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/5_exception_in_collect.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.*
-
-suspend fun main(): Unit = coroutineScope {
-
- val stocksFlow = stocksFlow()
-
- stocksFlow
- .onCompletion { cause ->
- if (cause == null) {
- println("Flow completed successfully!")
- } else {
- println("Flow completed exceptionally with $cause")
- }
- }
- .onEach { stock ->
- throw Exception("Exception in collect{}")
- println("Collected $stock")
- }.catch { throwable ->
- println("Handle exception in catch() operator $throwable")
- }
- .launchIn(this)
-}
-
-private fun stocksFlow(): Flow = flow {
- emit("Apple")
- emit("Microsoft")
-
- throw Exception("Network Request Failed!")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/6_exception_transparency.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/6_exception_transparency.kt
deleted file mode 100644
index 9a61479e..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/6_exception_transparency.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.flow
-
-suspend fun main(): Unit = coroutineScope {
-
- flow {
- try {
- emit(1)
- } catch (e: Exception) {
- println("Catch exception in flow builder.")
- }
- }.collect { emittedValue ->
- throw Exception("Exception in collect{}")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/7_inlining.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/7_inlining.kt
deleted file mode 100644
index 7cce932f..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/7_inlining.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.flow
-
-suspend fun main(): Unit = coroutineScope {
-
- flow {
- emit(1)
- emit(2)
- emit(3)
- }.collect {
- println("Collected $it")
- }
-}
-
-val inlinedFlow = flow {
- println("Collected 1")
- println("Collected 2")
- println("Collected 3")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/8_retry.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/8_retry.kt
deleted file mode 100644
index b399911b..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/exceptionhandling/8_retry.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.exceptionhandling
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.catch
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.retryWhen
-import kotlinx.coroutines.launch
-
-suspend fun main(): Unit = coroutineScope {
-
- launch {
- stocksFlow()
- .catch { throwable ->
- println("Handle exception in catch() operator $throwable")
- }
- .collect { stockData ->
- println("Collected $stockData")
- }
- }
-}
-
-private fun stocksFlow(): Flow = flow {
-
- repeat(5) { index ->
-
- delay(1000) // Network call
-
- if (index < 4) {
- emit("New Stock data")
- } else {
- throw NetworkException("Network Request Failed!")
- }
- }
-}.retryWhen { cause, attempt ->
- println("Enter retry() with $cause")
- delay(1000 * (attempt + 1))
- cause is NetworkException
-}
-
-class NetworkException(message: String) : Exception(message)
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/hot_and_cold_flows/1-flows_are_cold.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/hot_and_cold_flows/1-flows_are_cold.kt
deleted file mode 100644
index ef99af1f..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/hot_and_cold_flows/1-flows_are_cold.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.hot_and_cold_flows
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.launch
-
-fun coldFlow() = flow {
- println("Emitting 1")
- emit(1)
-
- delay(1000)
- println("Emitting 2")
- emit(2)
-
- delay(1000)
- println("Emitting 3")
- emit(3)
-}
-
-suspend fun main(): Unit = coroutineScope {
-
- launch {
- coldFlow()
- .collect {
- println("Collector 1 collects: $it")
- }
- }
-
- launch {
- coldFlow()
- .collect {
- println("Collector 2 collects: $it")
- }
- }
-}
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/hot_and_cold_flows/2_sharedflows_are_hot.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/hot_and_cold_flows/2_sharedflows_are_hot.kt
deleted file mode 100644
index a39027f5..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/hot_and_cold_flows/2_sharedflows_are_hot.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.hot_and_cold_flows
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.launch
-
-fun main() {
-
- val sharedFlow = MutableSharedFlow()
-
- val scope = CoroutineScope(Dispatchers.Default)
-
- scope.launch {
- repeat(5) {
- println("SharedFlow emits $it")
- sharedFlow.emit(it)
- delay(200)
- }
- }
-
- scope.launch {
- sharedFlow.collect{
- println("Collected $it in collector 1")
- }
- }
-
- scope.launch {
- sharedFlow.collect{
- println("Collected $it in collector 2")
- }
- }
-
- Thread.sleep(1500)
-}
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/1_map.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/1_map.kt
deleted file mode 100644
index f11c94e3..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/1_map.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.mapNotNull
-
-suspend fun main() {
-
- flowOf(1, 2, 3, 4, 5)
- .mapNotNull { "Emission $it" }
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/2_filter.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/2_filter.kt
deleted file mode 100644
index 7ce51e11..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/2_filter.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.filterIsInstance
-import kotlinx.coroutines.flow.flowOf
-
-suspend fun main() {
-
- flowOf(1, 2, 3, 4, 5)
- .filterIsInstance()
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/3_take.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/3_take.kt
deleted file mode 100644
index f84ff419..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/3_take.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.takeWhile
-
-suspend fun main() {
-
- flowOf(1, 2, 3, 4, 5)
- .takeWhile { it < 3 }
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/4_drop.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/4_drop.kt
deleted file mode 100644
index 1bb3c389..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/4_drop.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.dropWhile
-import kotlinx.coroutines.flow.flowOf
-
-suspend fun main() {
-
- flowOf(1, 2, 3, 4, 5, 1)
- .dropWhile { it < 2 }
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/5_transform.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/5_transform.kt
deleted file mode 100644
index 5f8e68e6..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/5_transform.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.transform
-
-suspend fun main() {
-
- flowOf(1, 2, 3, 4, 5, 1)
- .transform {
- emit(it)
- emit(it * 10)
- }
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/6_withIndex.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/6_withIndex.kt
deleted file mode 100644
index 07211da7..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/6_withIndex.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.withIndex
-
-suspend fun main() {
-
- flowOf(1, 2, 3, 4, 5, 1)
- .withIndex()
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/7_distinctUntilChanged.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/7_distinctUntilChanged.kt
deleted file mode 100644
index c3fc74b3..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/intermediate_operators/7_distinctUntilChanged.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.intermediate_operators
-
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
-
-suspend fun main() {
-
- flowOf(1, 1, 2, 3, 4, 5, 1)
- .distinctUntilChanged()
- .collect { collectedValue ->
- println(collectedValue)
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/stateflow/1-stateflow.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/stateflow/1-stateflow.kt
deleted file mode 100644
index ef5577bb..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/stateflow/1-stateflow.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.stateflow
-
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.update
-import kotlinx.coroutines.launch
-
-suspend fun main() {
-
- val counter = MutableStateFlow(0)
-
- println(counter.value)
-
- coroutineScope {
- repeat(10_000) {
- launch {
- counter.update { currentValue ->
- currentValue + 1
- }
- }
- }
- }
-
- println(counter.value)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/1_flows_vs_lists.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/1_flows_vs_lists.kt
deleted file mode 100644
index a5016b60..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/1_flows_vs_lists.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- val list = buildList {
- add(1)
- println("add 1 to list")
-
- add(2)
- println("add 2 to list")
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/2_collect.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/2_collect.kt
deleted file mode 100644
index 3c4bf8ce..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/2_collect.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.runBlocking
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- runBlocking {
- flow.collect { receivedValue ->
- println("Received value $receivedValue")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/3_first.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/3_first.kt
deleted file mode 100644
index 598ae372..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/3_first.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.runBlocking
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- runBlocking {
- val item = flow.first { it > 1 }
- println("Received $item")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/4_last.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/4_last.kt
deleted file mode 100644
index c1700634..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/4_last.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.last
-import kotlinx.coroutines.runBlocking
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- runBlocking {
- val item = flow.last()
- println("Received $item")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/5_single.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/5_single.kt
deleted file mode 100644
index a7d6959d..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/5_single.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.single
-import kotlinx.coroutines.runBlocking
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- // emit(2)
- }
-
- runBlocking {
- val item = flow.single()
- println("Received $item")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/6_toList_toSet.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/6_toList_toSet.kt
deleted file mode 100644
index d3b54d19..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/6_toList_toSet.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.toList
-import kotlinx.coroutines.flow.toSet
-import kotlinx.coroutines.runBlocking
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- runBlocking {
- val item = flow.toSet()
- println("Received $item")
- }
-
- runBlocking {
- val item = flow.toList()
- println("Received $item")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/7_fold.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/7_fold.kt
deleted file mode 100644
index 4159022f..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/7_fold.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.fold
-import kotlinx.coroutines.runBlocking
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- runBlocking {
- val item = flow.fold(5) { accumulator, emittedItem ->
- accumulator + emittedItem
- }
- println("Received $item")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/8_launchIn.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/8_launchIn.kt
deleted file mode 100644
index af6082eb..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/flow/terminal_operators/8_launchIn.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.flow.terminal_operators
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.launch
-import kotlin.coroutines.EmptyCoroutineContext
-
-fun main() {
-
- val flow = flow {
- delay(100)
-
- println("Emitting first value")
- emit(1)
-
- delay(100)
-
- println("Emitting second value")
- emit(2)
- }
-
- val scope = CoroutineScope(EmptyCoroutineContext)
-
- flow
- .onEach { println("Received $it with launchIn() - 1") }
- .launchIn(scope)
-
- flow
- .onEach { println("Received $it with launchIn() - 2") }
- .launchIn(scope)
-
- scope.launch {
- flow.collect {
- println("Received $it in collect - 1")
- }
- flow.collect {
- println("Receive $it in collect - 2")
- }
- }
-
- Thread.sleep(1000)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/10_how_delay_works.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/10_how_delay_works.kt
deleted file mode 100644
index 50ea69a1..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/10_how_delay_works.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import android.os.Handler
-import android.os.Looper
-import kotlinx.coroutines.async
-import kotlinx.coroutines.joinAll
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
- println("main starts")
- joinAll(
- async { delayDemonstration(1, 500) },
- async { delayDemonstration(2, 300) }
- )
- println("main ends")
-}
-
-suspend fun delayDemonstration(number: Int, delay: Long) {
- println("Coroutine $number starts work")
-
- // delay(delay)
-
- Handler(Looper.getMainLooper())
- .postDelayed({
- println("Coroutine $number has finished")
- }, 500)
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/1_routines.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/1_routines.kt
deleted file mode 100644
index fe83e51c..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/1_routines.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-fun main() {
- println("main starts")
- routine(1, 500)
- routine(2, 300)
- println("main ends")
-}
-
-fun routine(number: Int, delay: Long) {
- println("Routine $number starts work")
- Thread.sleep(delay)
- println("Routine $number has finished")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/2_coroutines.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/2_coroutines.kt
deleted file mode 100644
index a7c1d0f0..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/2_coroutines.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlinx.coroutines.async
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.joinAll
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
- println("main starts")
- joinAll(
- async { coroutine(1, 500) },
- async { coroutine(2, 300) }
- )
- println("main ends")
-}
-
-suspend fun coroutine(number: Int, delay: Long) {
- println("Coroutine $number starts work")
- delay(delay)
- println("Coroutine $number has finished")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/3_routines_threads.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/3_routines_threads.kt
deleted file mode 100644
index ec1ecd33..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/3_routines_threads.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlin.concurrent.thread
-
-fun main() {
- println("main starts")
- threadRoutine(1, 500)
- threadRoutine(2, 300)
- Thread.sleep(1000)
- println("main ends")
-}
-
-fun threadRoutine(number: Int, delay: Long) {
- thread {
- println("Routine $number starts work")
- Thread.sleep(delay)
- println("Routine $number has finished")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/4_coroutines_with_thread_info.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/4_coroutines_with_thread_info.kt
deleted file mode 100644
index fd712c53..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/4_coroutines_with_thread_info.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlinx.coroutines.async
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.joinAll
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
- println("main starts")
- joinAll(
- async { threadInfoCoroutine(1, 500) },
- async { threadInfoCoroutine(2, 300) }
- )
- println("main ends")
-}
-
-suspend fun threadInfoCoroutine(number: Int, delay: Long) {
- println("Coroutine $number starts work on ${Thread.currentThread().name}")
- delay(delay)
- println("Coroutine $number has finished on ${Thread.currentThread().name}")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/5_starting_lots_of_coroutines.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/5_starting_lots_of_coroutines.kt
deleted file mode 100644
index 5c445957..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/5_starting_lots_of_coroutines.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
- repeat(1_000_000) {
- launch {
- delay(5000)
- print(".")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/7_starting_lots_of_threads.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/7_starting_lots_of_threads.kt
deleted file mode 100644
index 0ecae8c1..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/7_starting_lots_of_threads.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlin.concurrent.thread
-
-fun main() {
- repeat(1_000_000) {
- thread {
- Thread.sleep(5000)
- print(".")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/8_suspending_coroutines.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/8_suspending_coroutines.kt
deleted file mode 100644
index 4ceb0803..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/8_suspending_coroutines.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlinx.coroutines.async
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.joinAll
-import kotlinx.coroutines.runBlocking
-
-fun main() = runBlocking {
- println("main starts")
- joinAll(
- async { suspendingCoroutine(1, 500) },
- async { suspendingCoroutine(2, 300) },
- async {
- repeat(5) {
- println("other tasks is working on ${Thread.currentThread().name}")
- delay(100)
- }
- }
- )
- println("main ends")
-}
-
-suspend fun suspendingCoroutine(number: Int, delay: Long) {
- println("Coroutine $number starts work on ${Thread.currentThread().name}")
- delay(delay)
- println("Coroutine $number has finished on ${Thread.currentThread().name}")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/9_coroutine_in_different_threads.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/9_coroutine_in_different_threads.kt
deleted file mode 100644
index 3ac7a3f3..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/fundamentals/9_coroutine_in_different_threads.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.fundamentals
-
-import kotlinx.coroutines.*
-
-fun main() = runBlocking {
- println("main starts")
- joinAll(
- async { threadSwitchingCoroutine(1, 500) },
- async { threadSwitchingCoroutine(2, 300) }
- )
- println("main ends")
-}
-
-suspend fun threadSwitchingCoroutine(number: Int, delay: Long) {
- println("Coroutine $number starts work on ${Thread.currentThread().name}")
- delay(delay)
- withContext(Dispatchers.Default) {
- println("Coroutine $number has finished on ${Thread.currentThread().name}")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/1_coroutines_need_to_be_started_in_scope.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/1_coroutines_need_to_be_started_in_scope.kt
deleted file mode 100644
index 1a26d45e..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/1_coroutines_need_to_be_started_in_scope.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-val scope = CoroutineScope(Dispatchers.Default)
-
-fun main() = runBlocking {
-
- val job = scope.launch {
- delay(100)
- println("Coroutine completed")
- }
-
- job.invokeOnCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Coroutine was cancelled")
- }
- }
-
- delay(50)
- onDestroy()
-}
-
-fun onDestroy() {
- println("life-time of scope ends")
- scope.cancel()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/2_job_hierarchy.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/2_job_hierarchy.kt
deleted file mode 100644
index d4b8dd0e..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/2_job_hierarchy.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-fun main() {
-
- val scopeJob = Job()
- val scope = CoroutineScope(Dispatchers.Default + scopeJob)
-
- val passedJob = Job()
- val coroutineJob = scope.launch(passedJob) {
- println("Starting coroutine")
- delay(1000)
- }
-
- println("passedJob and coroutineJob are references to the same job object: ${passedJob === coroutineJob}")
-
- println("Is coroutineJob a child of scopeJob? =>${scopeJob.children.contains(coroutineJob)}")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/3_parents_wait_for_children.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/3_parents_wait_for_children.kt
deleted file mode 100644
index 24759e1c..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/3_parents_wait_for_children.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-fun main() = runBlocking {
-
- val scope = CoroutineScope(Dispatchers.Default)
-
- val parentCoroutineJob = scope.launch {
- launch {
- delay(1000)
- println("Child Coroutine 1 has completed!")
- }
- launch {
- delay(1000)
- println("Child Coroutine 2 has completed!")
- }
- }
-
- parentCoroutineJob.join()
- println("Parent Coroutine has completed!")
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/4_cancelling_parents_and_children.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/4_cancelling_parents_and_children.kt
deleted file mode 100644
index b4cbc7a2..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/4_cancelling_parents_and_children.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-fun main() = runBlocking {
-
- val scope = CoroutineScope(Dispatchers.Default)
-
- scope.coroutineContext[Job]!!.invokeOnCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Parent job was cancelled")
- }
- }
-
- val childCoroutine1Job = scope.launch {
- delay(1000)
- println("Coroutine 1 completed")
- }
- childCoroutine1Job.invokeOnCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Coroutine 1 was cancelled!")
- }
- }
-
- scope.launch {
- delay(1000)
- println("Coroutine 2 completed")
- }.invokeOnCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Coroutine 2 was cancelled!")
- }
- }
-
- delay(200)
-
- childCoroutine1Job.cancelAndJoin()
-
- // scope.coroutineContext[Job]!!.cancelAndJoin()
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/5_exception_propagation.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/5_exception_propagation.kt
deleted file mode 100644
index baf323a0..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/5_exception_propagation.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-fun main() {
-
- val exceptionHandler = CoroutineExceptionHandler { context, exception ->
- println("Caught exception $exception")
- }
-
- val scope = CoroutineScope(SupervisorJob() + exceptionHandler)
-
- scope.launch {
- println("Coroutine 1 starts")
- delay(50)
- println("Coroutine 1 fails")
- throw RuntimeException()
- }
-
- scope.launch {
- println("Coroutine 2 starts")
- delay(500)
- println("Coroutine 2 completed")
- }.invokeOnCompletion { throwable ->
- if (throwable is CancellationException) {
- println("Coroutine 2 got cancelled!")
- }
- }
-
- Thread.sleep(1000)
-
- println("Scope got cancelled: ${!scope.isActive}")
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/6_globalscope.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/6_globalscope.kt
deleted file mode 100644
index 20d278d9..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/6_globalscope.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-fun main() = runBlocking {
-
- println("Job of GlobalScope: ${GlobalScope.coroutineContext[Job]}")
-
- val coroutineExceptionHandler = CoroutineExceptionHandler { context, throwable ->
-
- }
- val job = GlobalScope.launch(coroutineExceptionHandler) {
- val child = launch {
- delay(50)
- throw RuntimeException()
- println("Still running")
- delay(50)
- println("Still running")
- delay(50)
- println("Still running")
- delay(50)
- println("Still running")
- }
- }
-
- delay(100)
-
- job.cancel()
-
- delay(300)
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/7_scoping_functions.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/7_scoping_functions.kt
deleted file mode 100644
index a090257c..00000000
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/playground/structuredconcurrency/7_scoping_functions.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.structuredconcurrency
-
-import kotlinx.coroutines.*
-
-fun main() {
-
- val scope = CoroutineScope(Job())
-
- scope.launch {
-
- doSomeTasks()
-
- launch {
- println("Starting Task 3")
- delay(300)
- println("Task 3 completed")
- }
- }
-
- Thread.sleep(1000)
-}
-
-suspend fun doSomeTasks() = coroutineScope {
- launch {
- println("Starting Task 1")
- delay(100)
- println("Task 1 completed")
- }
-
- launch {
- println("Starting Task 2")
- delay(200)
- println("Task 2 completed")
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModel.kt
index 90c6a061..0ca79c38 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModel.kt
@@ -1,25 +1,16 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.launch
-import timber.log.Timber
class PerformSingleNetworkRequestViewModel(
private val mockApi: MockApi = mockApi()
) : BaseViewModel() {
+
fun performSingleNetworkRequest() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- try {
- val recentAndroidVersions = mockApi.getRecentAndroidVersions()
- uiState.value = UiState.Success(recentAndroidVersions)
- } catch (exception: Exception) {
- Timber.e(exception)
- uiState.value = UiState.Error("Network Request failed!")
- }
- }
+
+
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/UiState.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/UiState.kt
index 4dd9a007..e9f5795f 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/UiState.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/UiState.kt
@@ -3,7 +3,7 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
sealed class UiState {
- object Loading : UiState()
+ data object Loading : UiState()
data class Success(val recentVersions: List) : UiState()
data class Error(val message: String) : UiState()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModel.kt
index f61e5f3c..0b4062a4 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModel.kt
@@ -1,52 +1,10 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase10
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import java.math.BigInteger
-import kotlin.system.measureTimeMillis
-class CalculationInBackgroundViewModel(
- private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
-) : BaseViewModel() {
+class CalculationInBackgroundViewModel : BaseViewModel() {
fun performCalculation(factorialOf: Int) {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- try {
- var result: BigInteger = BigInteger.ZERO
- val computationDuration = measureTimeMillis {
- result = calculateFactorialOf(factorialOf)
- }
- var resultString = ""
- val stringConversionDuration = measureTimeMillis {
- resultString = convertToString(result)
- }
-
- uiState.value =
- UiState.Success(resultString, computationDuration, stringConversionDuration)
- } catch (exception: Exception) {
- UiState.Error("Error while calculating result")
- }
- }
}
-
- // factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
- private suspend fun calculateFactorialOf(number: Int): BigInteger =
- withContext(defaultDispatcher) {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- }
- factorial
- }
-
- private suspend fun convertToString(number: BigInteger): String =
- withContext(defaultDispatcher) {
- number.toString()
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase11/CooperativeCancellationViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase11/CooperativeCancellationViewModel.kt
index 639ed93a..1dbe3178 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase11/CooperativeCancellationViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase11/CooperativeCancellationViewModel.kt
@@ -3,71 +3,22 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import kotlinx.coroutines.*
-import java.math.BigInteger
-import kotlin.system.measureTimeMillis
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
class CooperativeCancellationViewModel(
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
) : ViewModel() {
- private var calculationJob: Job? = null
-
fun performCalculation(factorialOf: Int) {
- uiState.value = UiState.Loading
- calculationJob = viewModelScope.launch {
- try {
-
- var result: BigInteger = BigInteger.ZERO
- val computationDuration = measureTimeMillis {
- result = calculateFactorialOf(factorialOf)
- }
-
- var resultString = ""
- val stringConversionDuration = measureTimeMillis {
- resultString = convertToString(result)
- }
- uiState.value =
- UiState.Success(resultString, computationDuration, stringConversionDuration)
- } catch (exception: Exception) {
- uiState.value = if (exception is CancellationException) {
- UiState.Error("Calculation was cancelled")
- } else {
- UiState.Error("Error while calculating result")
- }
- }
- }
}
- // factorial of n (n!) = 1 * 2 * 3 * 4 * ... * n
- private suspend fun calculateFactorialOf(number: Int): BigInteger =
- withContext(defaultDispatcher) {
- var factorial = BigInteger.ONE
- for (i in 1..number) {
-
- // yield enables cooperative cancellations
- // alternatives:
- // - ensureActive()
- // - isActive() - possible to do clean up tasks with
- yield()
-
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- }
- factorial
- }
+ fun cancelCalculation() {
- private suspend fun convertToString(number: BigInteger): String =
- withContext(defaultDispatcher) {
- number.toString()
- }
+ }
fun uiState(): LiveData = uiState
- fun cancelCalculation() {
- calculationJob?.cancel()
- }
-
private val uiState: MutableLiveData = MutableLiveData()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/CalculationInSeveralCoroutinesViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/CalculationInSeveralCoroutinesViewModel.kt
index 376693a5..f2a5f3a7 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/CalculationInSeveralCoroutinesViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/CalculationInSeveralCoroutinesViewModel.kt
@@ -1,11 +1,8 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase12
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
import java.math.BigInteger
import kotlin.system.measureTimeMillis
@@ -19,31 +16,25 @@ class CalculationInSeveralCoroutinesViewModel(
numberOfCoroutines: Int
) {
uiState.value = UiState.Loading
- viewModelScope.launch {
- var factorialResult = BigInteger.ZERO
- val computationDuration = measureTimeMillis {
- factorialResult =
- factorialCalculator.calculateFactorial(
- factorialOf,
- numberOfCoroutines
- )
- }
-
- var resultString = ""
- val stringConversionDuration = measureTimeMillis {
- resultString = convertToString(factorialResult)
- }
+ var factorialResult = BigInteger.ZERO
+ val computationDuration = measureTimeMillis {
+ factorialResult =
+ factorialCalculator.calculateFactorial(
+ factorialOf,
+ numberOfCoroutines
+ )
+ }
- uiState.value =
- UiState.Success(resultString, computationDuration, stringConversionDuration)
+ var resultString = ""
+ val stringConversionDuration = measureTimeMillis {
+ resultString = convertToString(factorialResult)
}
+
+ uiState.value =
+ UiState.Success(resultString, computationDuration, stringConversionDuration)
}
- private suspend fun convertToString(
- number: BigInteger
- ): String =
- withContext(defaultDispatcher) {
- number.toString()
- }
+ // TODO: execute on background thread
+ private fun convertToString(number: BigInteger): String = number.toString()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculator.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculator.kt
index 1e621b0d..e4637d2f 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculator.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculator.kt
@@ -1,44 +1,41 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase12
-import com.lukaslechner.coroutineusecasesonandroid.utils.addCoroutineDebugInfo
-import kotlinx.coroutines.*
-import timber.log.Timber
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
import java.math.BigInteger
class FactorialCalculator(
private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default
) {
- suspend fun calculateFactorial(
+ fun calculateFactorial(
factorialOf: Int,
numberOfCoroutines: Int
): BigInteger {
- return withContext(defaultDispatcher) {
- val subRanges = createSubRangeList(factorialOf, numberOfCoroutines)
- subRanges.map { subRange ->
- async {
- calculateFactorialOfSubRange(subRange)
- }
- }.awaitAll()
- .fold(BigInteger.ONE, { acc, element ->
- ensureActive()
- acc.multiply(element)
- })
- }
+
+ // TODO: create sub range list *on background thread*
+ val subRanges = createSubRangeList(factorialOf, numberOfCoroutines)
+
+
+ // TODO: calculate factorial of each subrange in separate coroutine
+ // use calculateFactorialOfSubRange(subRange) therefore
+
+
+ // TODO: create factorial result by multiplying all sub-results and return this
+ // result
+
+ return BigInteger.ZERO
}
- suspend fun calculateFactorialOfSubRange(
+ // TODO: execute on background thread
+ fun calculateFactorialOfSubRange(
subRange: SubRange
): BigInteger {
- return withContext(defaultDispatcher) {
- Timber.d(addCoroutineDebugInfo("Calculate factorial of $subRange"))
- var factorial = BigInteger.ONE
- for (i in subRange.start..subRange.end) {
- ensureActive()
- factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
- }
- factorial
+ var factorial = BigInteger.ONE
+ for (i in subRange.start..subRange.end) {
+ factorial = factorial.multiply(BigInteger.valueOf(i.toLong()))
}
+ return factorial
}
fun createSubRangeList(
@@ -63,4 +60,5 @@ class FactorialCalculator(
}
}
+
data class SubRange(val start: Int, val end: Int)
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase13/ExceptionHandlingViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase13/ExceptionHandlingViewModel.kt
index a4e98d83..e45bad1f 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase13/ExceptionHandlingViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase13/ExceptionHandlingViewModel.kt
@@ -1,6 +1,5 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase13
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
import kotlinx.coroutines.*
@@ -11,59 +10,14 @@ class ExceptionHandlingViewModel(
) : BaseViewModel() {
fun handleExceptionWithTryCatch() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- try {
- api.getAndroidVersionFeatures(27)
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed: $exception")
- }
- }
}
fun handleWithCoroutineExceptionHandler() {
- val exceptionHandler = CoroutineExceptionHandler { _, exception ->
- uiState.value = UiState.Error("Network Request failed!! $exception")
- }
- uiState.value = UiState.Loading
- viewModelScope.launch(exceptionHandler) {
- api.getAndroidVersionFeatures(27)
- }
}
fun showResultsEvenIfChildCoroutineFails() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- supervisorScope {
- val oreoFeaturesDeferred = async { api.getAndroidVersionFeatures(27) }
- val pieFeaturesDeferred = async { api.getAndroidVersionFeatures(28) }
- val android10FeaturesDeferred = async { api.getAndroidVersionFeatures(29) }
-
- val versionFeatures = listOf(
- oreoFeaturesDeferred,
- pieFeaturesDeferred,
- android10FeaturesDeferred
- ).mapNotNull {
- try {
- it.await()
- } catch (exception: Exception) {
- // We have to re-throw cancellation exceptions so that
- // our Coroutine gets cancelled immediately.
- // Otherwise, the CancellationException is ignored
- // and the Coroutine keeps running until it reaches the next
- // suspension point.
- if (exception is CancellationException) {
- throw exception
- }
- Timber.e("Error loading feature data!")
- null
- }
- }
- uiState.value = UiState.Success(versionFeatures)
- }
- }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepository.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepository.kt
index 29176147..078d6143 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepository.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepository.kt
@@ -3,9 +3,6 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
-import timber.log.Timber
class AndroidVersionRepository(
private var database: AndroidVersionDao,
@@ -18,20 +15,10 @@ class AndroidVersionRepository(
}
suspend fun loadAndStoreRemoteAndroidVersions(): List {
- return scope.async {
- val recentVersions = api.getRecentAndroidVersions()
- Timber.d("Recent Android versions loaded")
- for (recentVersion in recentVersions) {
- Timber.d("Insert $recentVersion to database")
- database.insert(recentVersion.mapToEntity())
- }
- recentVersions
- }.await()
- }
+ return emptyList()
+ }
fun clearDatabase() {
- scope.launch {
- database.clear()
- }
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModel.kt
index 2cc394f5..5b77d847 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModel.kt
@@ -3,6 +3,9 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2
import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
class Perform2SequentialNetworkRequestsViewModel(
@@ -10,19 +13,30 @@ class Perform2SequentialNetworkRequestsViewModel(
) : BaseViewModel() {
fun perform2SequentialNetworkRequest() {
+
uiState.value = UiState.Loading
+
+ // study inside documentation of this later
+ //also taught later in course
viewModelScope.launch {
+ //just looks like normal fxn call
+ // AT first it looks like we are synchronously calling 2 functions and blocking the main thread
+ // but actually that is not the case, main thread is not blocked
+ //Suspend fxns. when implemented correctly are non-blocking
try {
val recentVersions = mockApi.getRecentAndroidVersions()
- val mostRecentVersion = recentVersions.last()
-
- val featuresOfMostRecentVersion =
- mockApi.getAndroidVersionFeatures(mostRecentVersion.apiLevel)
-
- uiState.value = UiState.Success(featuresOfMostRecentVersion)
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed")
+ val featuresOfLatestVersion = mockApi
+ .getAndroidVersionFeatures(
+ recentVersions.last().apiLevel
+ )
+ uiState.value = UiState.Success(featuresOfLatestVersion)
+ } catch (e: Exception) {
+ uiState.value = UiState.Error("Network request failed")
}
+ // exception hanndling here is also easy
}
+
+
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModel.kt
index dbc60105..7be3400c 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModel.kt
@@ -1,5 +1,6 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2.callbacks
+import androidx.lifecycle.AndroidViewModel
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
@@ -11,55 +12,68 @@ class SequentialNetworkRequestsCallbacksViewModel(
private val mockApi: CallbackMockApi = mockApi()
) : BaseViewModel() {
- private var getAndroidVersionsCall: Call>? = null
- private var getAndroidFeaturesCall: Call? = null
+ var getVersions: Call>? = null;
+ var getFeaturesCall: Call? = null;
fun perform2SequentialNetworkRequest() {
-
uiState.value = UiState.Loading
- getAndroidVersionsCall = mockApi.getRecentAndroidVersions()
- getAndroidVersionsCall!!.enqueue(object : Callback> {
- override fun onFailure(call: Call>, t: Throwable) {
- uiState.value = UiState.Error("Network Request failed")
- }
+ getVersions = mockApi.getRecentAndroidVersions()
+ getVersions!!.enqueue(
+ object : Callback>{
+ override fun onResponse(
+ call: Call>,
+ response: Response>
+ ) {
+ if(response.isSuccessful) { //status code >= 200 and <300
+ val latestVersion = response.body()!!.last()
+
+ //Perform Second Call only if first call was successful.
- override fun onResponse(
- call: Call>,
- response: Response>
- ) {
- if (response.isSuccessful) {
- val mostRecentVersion = response.body()!!.last()
- getAndroidFeaturesCall =
- mockApi.getAndroidVersionFeatures(mostRecentVersion.apiLevel)
- getAndroidFeaturesCall!!.enqueue(object : Callback {
- override fun onFailure(call: Call, t: Throwable) {
- uiState.value = UiState.Error("Network Request failed")
- }
+ getFeaturesCall = mockApi.getAndroidVersionFeatures(latestVersion.apiLevel)
+ getFeaturesCall!!.enqueue(
+ object : Callback {
+ override fun onResponse(
+ call: Call,
+ response: Response
+ ) {
+ if(response.isSuccessful) {
+ val featuresOfMostRecentVersion = response.body()!!
+ uiState.value = UiState.Success(
+ featuresOfMostRecentVersion
+ )
+ } else {
+ uiState.value = UiState.Error("Network request failed")
+ }
+ }
- override fun onResponse(
- call: Call,
- response: Response
- ) {
- if (response.isSuccessful) {
- val featuresOfMostRecentVersion = response.body()!!
- uiState.value = UiState.Success(featuresOfMostRecentVersion)
- } else {
- uiState.value = UiState.Error("Network Request failed")
- }
- }
- })
- } else {
- uiState.value = UiState.Error("Network Request failed")
+ override fun onFailure(call: Call, t: Throwable) {
+ uiState.value = UiState.Error("Something went wrong")
+ }
+ }
+
+ )
+ } else {
+ uiState.value = UiState.Error("Network request failed")
+ }
+ }
+
+ override fun onFailure(call: Call>, t: Throwable) {
+ uiState.value = UiState.Error("Something went wrong")
}
}
- })
+ )
+
+ //since the callbacks are holding the reference to viewModel, it wont get garbage collected when user has left the screen.
+
}
override fun onCleared() {
+ //this cant access callbacks of prev fxn, so we make them top level.
+
super.onCleared()
- getAndroidVersionsCall?.cancel()
- getAndroidFeaturesCall?.cancel()
+ getVersions?.cancel()
+ getFeaturesCall?.cancel()
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/rx/SequentialNetworkRequestsRxViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/rx/SequentialNetworkRequestsRxViewModel.kt
index 66b4df79..6c117596 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/rx/SequentialNetworkRequestsRxViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/rx/SequentialNetworkRequestsRxViewModel.kt
@@ -14,24 +14,27 @@ class SequentialNetworkRequestsRxViewModel(
private val disposables = CompositeDisposable()
fun perform2SequentialNetworkRequest() {
- uiState.value = UiState.Loading
+ //use flatMap to chain the two network requests
+ // .subscribeOn(Schedulers.io()) is used to perform the network requests on a background thread
+ // .observeOn(AndroidSchedulers.mainThread()) is used to observe the results on the main thread
mockApi.getRecentAndroidVersions()
- .flatMap { androidVersions ->
- val recentVersion = androidVersions.last()
- mockApi.getAndroidVersionFeatures(recentVersion.apiLevel)
+ .flatMap {
+ val latestVersion = it.last()
+ mockApi.getAndroidVersionFeatures(latestVersion.apiLevel)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribeBy(
- onSuccess = { featureVersions ->
- uiState.value = UiState.Success(featureVersions)
+ .subscribeBy (
+ onSuccess = {
+ uiState.value = UiState.Success(it)
},
onError = {
- uiState.value = UiState.Error("Network Request failed.")
+ uiState.value = UiState.Error("Network request failed")
}
)
.addTo(disposables)
+
}
override fun onCleared() {
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModel.kt
index 35930fb0..f283c6f2 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModel.kt
@@ -1,79 +1,17 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase3
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.async
-import kotlinx.coroutines.awaitAll
-import kotlinx.coroutines.launch
class PerformNetworkRequestsConcurrentlyViewModel(
private val mockApi: MockApi = mockApi()
) : BaseViewModel() {
fun performNetworkRequestsSequentially() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- try {
- val oreoFeatures = mockApi.getAndroidVersionFeatures(27)
- val pieFeatures = mockApi.getAndroidVersionFeatures(28)
- val android10Features = mockApi.getAndroidVersionFeatures(29)
- val versionFeatures = listOf(oreoFeatures, pieFeatures, android10Features)
- uiState.value = UiState.Success(versionFeatures)
-
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed")
- }
- }
}
fun performNetworkRequestsConcurrently() {
- uiState.value = UiState.Loading
-
- val oreoFeaturesDeferred = viewModelScope.async { mockApi.getAndroidVersionFeatures(27) }
- val pieFeaturesDeferred = viewModelScope.async { mockApi.getAndroidVersionFeatures(28) }
- val android10FeaturesDeferred =
- viewModelScope.async { mockApi.getAndroidVersionFeatures(29) }
-
- viewModelScope.launch {
- try {
- val versionFeatures =
- awaitAll(oreoFeaturesDeferred, pieFeaturesDeferred, android10FeaturesDeferred)
- uiState.value = UiState.Success(versionFeatures)
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed")
- }
- }
-
- /*
-
- Alternatively:
-
- viewModelScope.launch {
- try {
- // we need to wrap this code with a coroutineScope block
- // otherwise the app would crash on unsuccessful network requests
- coroutineScope {
- val oreoFeaturesDeferred = async { mockApi.getAndroidVersionFeatures(27) }
- val pieFeaturesDeferred = async { mockApi.getAndroidVersionFeatures(28) }
- val android10FeaturesDeferred = async { mockApi.getAndroidVersionFeatures(29) }
-
- val oreoFeatures = oreoFeaturesDeferred.await()
- val pieFeatures = pieFeaturesDeferred.await()
- val android10Features = android10FeaturesDeferred.await()
-
- val versionFeatures = listOf(oreoFeatures, pieFeatures, android10Features)
-
- // other alternative: (but slightly different behavior when a deferred fails, see docs)
- // val versionFeatures = awaitAll(oreoFeaturesDeferred, pieFeaturesDeferred, android10FeaturesDeferred)
-
- uiState.value = UiState.Success(versionFeatures)
- }
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed")
- }
- }*/
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModel.kt
index 1a089480..900a78b6 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModel.kt
@@ -1,44 +1,17 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase4
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.async
-import kotlinx.coroutines.awaitAll
-import kotlinx.coroutines.launch
class VariableAmountOfNetworkRequestsViewModel(
private val mockApi: MockApi = mockApi()
) : BaseViewModel() {
fun performNetworkRequestsSequentially() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- try {
- val recentVersions = mockApi.getRecentAndroidVersions()
- val versionFeatures = recentVersions.map { androidVersion ->
- mockApi.getAndroidVersionFeatures(androidVersion.apiLevel)
- }
- uiState.value = UiState.Success(versionFeatures)
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed")
- }
- }
+
}
fun performNetworkRequestsConcurrently() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- try {
- val recentVersions = mockApi.getRecentAndroidVersions()
- val versionFeatures = recentVersions
- .map { androidVersion ->
- async { mockApi.getAndroidVersionFeatures(androidVersion.apiLevel) }
- }.awaitAll()
- uiState.value = UiState.Success(versionFeatures)
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed")
- }
- }
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModel.kt
index 6d4cb806..3a7baba3 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModel.kt
@@ -1,54 +1,14 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase5
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.TimeoutCancellationException
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withTimeout
-import kotlinx.coroutines.withTimeoutOrNull
class NetworkRequestWithTimeoutViewModel(
private val api: MockApi = mockApi()
) : BaseViewModel() {
fun performNetworkRequest(timeout: Long) {
- uiState.value = UiState.Loading
- // usingWithTimeout(timeout)
- usingWithTimeoutOrNull(timeout)
- }
-
- private fun usingWithTimeout(timeout: Long) {
- viewModelScope.launch {
- try {
- val recentVersions = withTimeout(timeout) {
- api.getRecentAndroidVersions()
- }
- uiState.value = UiState.Success(recentVersions)
- } catch (timeoutCancellationException: TimeoutCancellationException) {
- uiState.value = UiState.Error("Network Request timed out!")
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed!")
- }
- }
- }
-
- private fun usingWithTimeoutOrNull(timeout: Long) {
- viewModelScope.launch {
- try {
- val recentVersions = withTimeoutOrNull(timeout) {
- api.getRecentAndroidVersions()
- }
- if (recentVersions != null) {
- uiState.value = UiState.Success(recentVersions)
- } else {
- uiState.value = UiState.Error("Network Request timed out!")
- }
- } catch (exception: Exception) {
- uiState.value = UiState.Error("Network Request failed!")
- }
- }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModel.kt
index 00b433a5..068ba751 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModel.kt
@@ -1,50 +1,14 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase6
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import timber.log.Timber
class RetryNetworkRequestViewModel(
private val api: MockApi = mockApi()
) : BaseViewModel() {
fun performNetworkRequest() {
- uiState.value = UiState.Loading
- viewModelScope.launch {
- val numberOfRetries = 2
- try {
- retry(times = numberOfRetries) {
- val recentVersions = api.getRecentAndroidVersions()
- uiState.value = UiState.Success(recentVersions)
- }
- } catch (e: Exception) {
- uiState.value = UiState.Error("Network Request failed")
- }
- }
- }
- // retry with exponential backoff
- // inspired by https://stackoverflow.com/questions/46872242/how-to-exponential-backoff-retry-on-kotlin-coroutines
- private suspend fun retry(
- times: Int,
- initialDelayMillis: Long = 100,
- maxDelayMillis: Long = 1000,
- factor: Double = 2.0,
- block: suspend () -> T
- ): T {
- var currentDelay = initialDelayMillis
- repeat(times) {
- try {
- return block()
- } catch (exception: Exception) {
- Timber.e(exception)
- }
- delay(currentDelay)
- currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelayMillis)
- }
- return block() // last attempt
}
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase7/TimeoutAndRetryViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase7/TimeoutAndRetryViewModel.kt
index 1e0be0ce..856a539a 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase7/TimeoutAndRetryViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase7/TimeoutAndRetryViewModel.kt
@@ -1,10 +1,7 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase7
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.*
-import timber.log.Timber
class TimeoutAndRetryViewModel(
private val api: MockApi = mockApi()
@@ -15,57 +12,10 @@ class TimeoutAndRetryViewModel(
val numberOfRetries = 2
val timeout = 1000L
- val oreoVersionsDeferred = viewModelScope.async {
- retryWithTimeout(numberOfRetries, timeout) {
- api.getAndroidVersionFeatures(27)
- }
- }
+ // TODO: Exercise 3
+ // switch to branch "coroutine_course_full" to see solution
- val pieVersionsDeferred = viewModelScope.async {
- retryWithTimeout(numberOfRetries, timeout) {
- api.getAndroidVersionFeatures(28)
- }
- }
+ // run api.getAndroidVersionFeatures(27) and api.getAndroidVersionFeatures(28) in parallel
- viewModelScope.launch {
- try {
- val versionFeatures = listOf(
- oreoVersionsDeferred,
- pieVersionsDeferred
- ).awaitAll()
-
- uiState.value = UiState.Success(versionFeatures)
-
- } catch (e: Exception) {
- Timber.e(e)
- uiState.value = UiState.Error("Network Request failed")
- }
- }
- }
-
- private suspend fun retryWithTimeout(
- numberOfRetries: Int,
- timeout: Long,
- block: suspend () -> T
- ) = retry(numberOfRetries) {
- withTimeout(timeout) {
- block()
- }
- }
-
- private suspend fun retry(
- numberOfRetries: Int,
- delayBetweenRetries: Long = 100,
- block: suspend () -> T
- ): T {
- repeat(numberOfRetries) {
- try {
- return block()
- } catch (exception: Exception) {
- Timber.e(exception)
- }
- delay(delayBetweenRetries)
- }
- return block() // last attempt
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase8/RoomAndCoroutinesViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase8/RoomAndCoroutinesViewModel.kt
index e8f82780..ee96c7fc 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase8/RoomAndCoroutinesViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase8/RoomAndCoroutinesViewModel.kt
@@ -1,9 +1,7 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase8
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import kotlinx.coroutines.launch
class RoomAndCoroutinesViewModel(
private val api: MockApi,
@@ -11,35 +9,11 @@ class RoomAndCoroutinesViewModel(
) : BaseViewModel() {
fun loadData() {
- uiState.value = UiState.Loading.LoadFromDb
- viewModelScope.launch {
- val localVersions = database.getAndroidVersions()
- if (localVersions.isEmpty()) {
- uiState.value =
- UiState.Error(DataSource.DATABASE, "Database empty!")
- } else {
- uiState.value =
- UiState.Success(DataSource.DATABASE, localVersions.mapToUiModelList())
- }
-
- uiState.value = UiState.Loading.LoadFromNetwork
- try {
- val recentVersions = api.getRecentAndroidVersions()
- for (version in recentVersions) {
- database.insert(version.mapToEntity())
- }
- uiState.value = UiState.Success(DataSource.NETWORK, recentVersions)
- } catch (exception: Exception) {
- uiState.value = UiState.Error(DataSource.NETWORK, "Something went wrong!")
- }
- }
}
fun clearDatabase() {
- viewModelScope.launch {
- database.clear()
- }
+
}
}
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase9/DebuggingCoroutinesViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase9/DebuggingCoroutinesViewModel.kt
index 004b7a89..0f4a12eb 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase9/DebuggingCoroutinesViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase9/DebuggingCoroutinesViewModel.kt
@@ -1,56 +1,13 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase9
-import androidx.lifecycle.viewModelScope
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.utils.addCoroutineDebugInfo
-import kotlinx.coroutines.*
-import timber.log.Timber
class DebuggingCoroutinesViewModel(
private val api: MockApi = mockApi()
) : BaseViewModel() {
fun performSingleNetworkRequest() {
- uiState.value = UiState.Loading
- // This property needs to be set so that the coroutine name is printed when logging Thread.currentName()
- // System.setProperty("kotlinx.coroutines.debug", if (BuildConfig.DEBUG) "on" else "off")
- // It is set in [CoroutineUsecasesOnAndroidApplication]
-
- viewModelScope.launch(CoroutineName("Initial Coroutine")) {
- Timber.d(addCoroutineDebugInfo("Initial coroutine launched"))
- try {
- val recentVersions = api.getRecentAndroidVersions()
- Timber.d(addCoroutineDebugInfo("Recent Android Versions returned"))
- uiState.value = UiState.Success(recentVersions)
- } catch (exception: Exception) {
- Timber.d(addCoroutineDebugInfo("Loading recent Android Versions failed"))
- uiState.value = UiState.Error("Network Request failed")
- }
-
- // Perform two calculations in parallel
- val calculation1Deferred =
- async(CoroutineName("Calculation1")) { performCalculation1() }
- val calculation2Deferred =
- async(CoroutineName("Calculation2")) { performCalculation2() }
-
- Timber.d(addCoroutineDebugInfo("Result of Calculation1: ${calculation1Deferred.await()}"))
- Timber.d(addCoroutineDebugInfo("Result of Calculation2: ${calculation2Deferred.await()}"))
- }
- }
-
- private suspend fun performCalculation1() = withContext(Dispatchers.Default) {
- Timber.d(addCoroutineDebugInfo("Starting Calculation1"))
- delay(1000)
- Timber.d(addCoroutineDebugInfo("Calculation1 completed"))
- 13
- }
-
- private suspend fun performCalculation2() = withContext(Dispatchers.Default) {
- Timber.d(addCoroutineDebugInfo("Starting Calculation2"))
- delay(2000)
- Timber.d(addCoroutineDebugInfo("Calculation2 completed"))
- 42
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModel.kt
index 37690b43..e7a1f39e 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModel.kt
@@ -1,27 +1,12 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase1
import androidx.lifecycle.LiveData
-import androidx.lifecycle.asLiveData
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onCompletion
-import kotlinx.coroutines.flow.onStart
-import timber.log.Timber
class FlowUseCase1ViewModel(
stockPriceDataSource: StockPriceDataSource
) : BaseViewModel() {
- val currentStockPriceAsLiveData: LiveData = stockPriceDataSource
- .latestStockList
- .map { stockList ->
- UiState.Success(stockList) as UiState
- }
- .onStart {
- emit(UiState.Loading)
- }
- .onCompletion {
- Timber.tag("Flow").d("Flow has completed.")
- }
- .asLiveData()
+ val currentStockPriceAsLiveData: LiveData = TODO()
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase2/FlowUseCase2ViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase2/FlowUseCase2ViewModel.kt
index ad0b3370..a3956347 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase2/FlowUseCase2ViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase2/FlowUseCase2ViewModel.kt
@@ -1,11 +1,8 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase2
import androidx.lifecycle.LiveData
-import androidx.lifecycle.asLiveData
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.flow.*
-import timber.log.Timber
class FlowUseCase2ViewModel(
stockPriceDataSource: StockPriceDataSource,
@@ -26,48 +23,5 @@ class FlowUseCase2ViewModel(
*/
- val currentStockPriceAsLiveData: LiveData = stockPriceDataSource
- .latestStockList
- .withIndex()
- .onEach { indexedValue ->
- Timber.d("Processing emission ${indexedValue.index + 1}")
- }
- .map { indexedValue ->
- indexedValue.value
- }
- .take(10)
- .filter { stockList ->
- val googlePrice = stockList.find { stock ->
- stock.name == "Alphabet (Google)"
- }?.currentPrice ?: return@filter false
-
- googlePrice > 2300
- }
- .map { stockList ->
- stockList.filter { stock ->
- stock.country == "United States"
- }
- }
- .map { stockList ->
- stockList.filter { stock ->
- stock.name != "Apple" && stock.name != "Microsoft"
- }
- }
- .map { stockList ->
- stockList.mapIndexed { index, stock ->
- stock.copy(rank = index + 1)
- }
- }
- .map { stockList ->
- stockList.filter { stock ->
- stock.rank <= 10
- }
- }
- .map { stockList ->
- UiState.Success(stockList) as UiState
- }
- .onStart {
- emit(UiState.Loading)
- }
- .asLiveData(defaultDispatcher)
+ val currentStockPriceAsLiveData: LiveData = TODO()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/FlowUseCase3ViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/FlowUseCase3ViewModel.kt
index 371cf055..61965c86 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/FlowUseCase3ViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/FlowUseCase3ViewModel.kt
@@ -3,7 +3,6 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase3
import androidx.lifecycle.LiveData
import androidx.lifecycle.asLiveData
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
-import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
@@ -38,9 +37,5 @@ class FlowUseCase3ViewModel(
.onCompletion {
Timber.tag("Flow").d("Flow has completed.")
}
- .catch { throwable ->
- Timber.tag("Flow").d("Enter catch operator with $throwable")
- emit(UiState.Error("something went wrong"))
- }
.asLiveData()
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/StockPriceDataSource.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/StockPriceDataSource.kt
index baa396e8..c28daa02 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/StockPriceDataSource.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase3/StockPriceDataSource.kt
@@ -5,8 +5,6 @@ import com.lukaslechner.coroutineusecasesonandroid.usecases.flow.mock.Stock
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
-import kotlinx.coroutines.flow.retry
-import retrofit2.HttpException
import timber.log.Timber
interface StockPriceDataSource {
@@ -22,15 +20,5 @@ class NetworkStockPriceDataSource(mockApi: FlowMockApi) : StockPriceDataSource {
emit(currentStockList)
delay(5_000)
}
- }.retry { cause ->
- Timber.tag("Flow").d("Enter retry operator with $cause")
-
- val shouldRetry = cause is HttpException
-
- if (shouldRetry) {
- delay(5_000)
- }
-
- shouldRetry
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4Activity.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4Activity.kt
index dea1ad94..6213de43 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4Activity.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4Activity.kt
@@ -2,16 +2,12 @@ package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase4
import android.os.Bundle
import androidx.activity.viewModels
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.lifecycleScope
-import androidx.lifecycle.repeatOnLifecycle
import com.lukaslechner.coroutineusecasesonandroid.base.BaseActivity
import com.lukaslechner.coroutineusecasesonandroid.base.flowUseCase4Description
import com.lukaslechner.coroutineusecasesonandroid.databinding.ActivityFlowUsecase1Binding
import com.lukaslechner.coroutineusecasesonandroid.utils.setGone
import com.lukaslechner.coroutineusecasesonandroid.utils.setVisible
import com.lukaslechner.coroutineusecasesonandroid.utils.toast
-import kotlinx.coroutines.launch
import org.joda.time.LocalDateTime
import org.joda.time.format.DateTimeFormat
@@ -29,11 +25,9 @@ class FlowUseCase4Activity : BaseActivity() {
setContentView(binding.root)
binding.recyclerView.adapter = adapter
- lifecycleScope.launch {
- repeatOnLifecycle(Lifecycle.State.STARTED) {
- viewModel.currentStockPriceAsFlow.collect { uiState ->
- render(uiState)
- }
+ viewModel.currentStockPriceAsLiveData.observe(this) { uiState ->
+ if (uiState != null) {
+ render(uiState)
}
}
}
diff --git a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModel.kt b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModel.kt
index 81fbde85..c4a9fc78 100644
--- a/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModel.kt
+++ b/app/src/main/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModel.kt
@@ -1,24 +1,27 @@
package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase4
-import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.asLiveData
import com.lukaslechner.coroutineusecasesonandroid.base.BaseViewModel
-import kotlinx.coroutines.flow.*
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onCompletion
+import kotlinx.coroutines.flow.onStart
import timber.log.Timber
class FlowUseCase4ViewModel(
stockPriceDataSource: StockPriceDataSource
) : BaseViewModel() {
- val currentStockPriceAsFlow: StateFlow = stockPriceDataSource
+ val currentStockPriceAsLiveData: LiveData = stockPriceDataSource
.latestStockList
.map { stockList ->
UiState.Success(stockList) as UiState
}
+ .onStart {
+ emit(UiState.Loading)
+ }
.onCompletion {
Timber.tag("Flow").d("Flow has completed.")
- }.stateIn(
- scope = viewModelScope,
- initialValue = UiState.Loading,
- started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000)
- )
+ }
+ .asLiveData()
}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/playground/testing/1_testing_coroutines.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/playground/testing/1_testing_coroutines.kt
deleted file mode 100644
index f6e3f47a..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/playground/testing/1_testing_coroutines.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.playground.testing
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.currentTime
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-
-
-class SystemUnderTest {
-
- suspend fun functionWithDelay(): Int {
- delay(1000)
- return 42
- }
-}
-
-fun CoroutineScope.functionThatStartsNewCoroutine() {
- launch {
- delay(1000)
- println("Coroutine completed!")
- }
-}
-
-class TestClass {
-
- @Test
- fun `functionWithDelay should return 42`() = runTest {
-
- val realTimeStart = System.currentTimeMillis()
- val virtualTimeStart = currentTime
-
- functionThatStartsNewCoroutine()
- advanceTimeBy(1000)
-
- val realTimeDuration = System.currentTimeMillis() - realTimeStart
- val virtualTimeDuration = currentTime - virtualTimeStart
-
- println("Test took $realTimeDuration real ms")
- println("Test took $virtualTimeDuration virtual ms")
- }
-
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/FakeErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/FakeErrorApi.kt
deleted file mode 100644
index b82c4495..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/FakeErrorApi.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeErrorApi() : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/FakeSuccessApi.kt
deleted file mode 100644
index 06cbc476..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/FakeSuccessApi.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-
-class FakeSuccessApi : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModelTest.kt
deleted file mode 100644
index 9a70e9cb..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase1/PerformSingleNetworkRequestViewModelTest.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase1
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class PerformSingleNetworkRequestViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `should return Success when network request is successful`() = runTest {
- val fakeApi = FakeSuccessApi()
- val viewModel = PerformSingleNetworkRequestViewModel(fakeApi)
- observeViewModel(viewModel)
-
- assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performSingleNetworkRequest()
-
- assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(mockAndroidVersions)
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `should return Error when network request fails`() = runTest {
- val fakeApi = FakeErrorApi()
- val viewModel = PerformSingleNetworkRequestViewModel(fakeApi)
- observeViewModel(viewModel)
-
- assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performSingleNetworkRequest()
-
- assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed!")
- ),
- receivedUiStates
- )
- }
-
- private fun observeViewModel(viewModel: PerformSingleNetworkRequestViewModel) {
- viewModel.uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModelTest.kt
deleted file mode 100644
index d0864dcb..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase10/CalculationInBackgroundViewModelTest.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase10
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.StandardTestDispatcher
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class CalculationInBackgroundViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `performCalculation() should perform correct calculations`() = runTest {
- val viewModel =
- CalculationInBackgroundViewModel(StandardTestDispatcher(testScheduler)).apply {
- observe()
- }
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performCalculation(1)
- runCurrent()
-
- Assert.assertEquals(
- UiState.Loading,
- receivedUiStates.first()
- )
-
- Assert.assertEquals(
- "1",
- (receivedUiStates[1] as UiState.Success).result
- )
-
- receivedUiStates.clear()
-
- viewModel.performCalculation(2)
- runCurrent()
-
- Assert.assertEquals(
- UiState.Loading,
- receivedUiStates.first()
- )
-
- Assert.assertEquals(
- "2",
- (receivedUiStates[1] as UiState.Success).result
- )
-
- receivedUiStates.clear()
-
- viewModel.performCalculation(3)
- runCurrent()
-
- Assert.assertEquals(
- UiState.Loading,
- receivedUiStates.first()
- )
-
- Assert.assertEquals(
- "6",
- (receivedUiStates[1] as UiState.Success).result
- )
-
- }
-
- private fun CalculationInBackgroundViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculatorTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculatorTest.kt
deleted file mode 100644
index 756fe7d5..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase12/FactorialCalculatorTest.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase12
-
-import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import org.junit.Test
-import java.math.BigInteger
-
-@ExperimentalCoroutinesApi
-class FactorialCalculatorTest {
-
- @Test
- fun `createSubRangeList() should create correct range lists`() {
- val testDispatcher = UnconfinedTestDispatcher()
- val factorialCalculator = FactorialCalculator(testDispatcher)
-
- assertEquals(
- listOf(
- SubRange(1, 3),
- SubRange(4, 6),
- SubRange(7, 9)
- ),
- factorialCalculator.createSubRangeList(9, 3)
- )
-
- assertEquals(
- listOf(
- SubRange(1, 3),
- SubRange(4, 6),
- SubRange(7, 10)
- ),
- factorialCalculator.createSubRangeList(10, 3)
- )
-
- assertEquals(
- listOf(
- SubRange(1, 3),
- SubRange(4, 6),
- SubRange(7, 11)
- ),
- factorialCalculator.createSubRangeList(11, 3)
- )
- }
-
- @Test
- fun calculateFactorialOfSubRange() = runBlocking {
- val testDispatcher = UnconfinedTestDispatcher()
- val factorialCalculator = FactorialCalculator(testDispatcher)
-
- assertEquals(
- BigInteger.valueOf(6),
- factorialCalculator.calculateFactorialOfSubRange(SubRange(1, 3))
- )
- assertEquals(
- BigInteger.valueOf(120),
- factorialCalculator.calculateFactorialOfSubRange(SubRange(4, 6))
- )
- assertEquals(
- BigInteger.valueOf(55440),
- factorialCalculator.calculateFactorialOfSubRange(SubRange(7, 11))
- )
- }
-
- @Test
- fun calculateFactorial() = runBlocking {
- val testDispatcher = UnconfinedTestDispatcher()
- val factorialCalculator = FactorialCalculator(testDispatcher)
-
- assertEquals(
- BigInteger.valueOf(3628800),
- factorialCalculator.calculateFactorial(10, 3)
- )
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepositoryTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepositoryTest.kt
deleted file mode 100644
index 0ee83fac..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/AndroidVersionRepositoryTest.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase14
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-
-@ExperimentalCoroutinesApi
-class AndroidVersionRepositoryTest {
-
- @Test
- fun `getLocalAndroidVersions() should return android versions from database`() = runTest {
- val fakeDatabase = FakeDatabase()
-
- val repository = AndroidVersionRepository(fakeDatabase, this)
- assertEquals(mockAndroidVersions, repository.getLocalAndroidVersions())
- }
-
- @Test
- fun `loadRecentAndroidVersions() should return android versions from network`() = runTest {
- val fakeDatabase = FakeDatabase()
- val fakeApi = FakeApi()
- val repository = AndroidVersionRepository(
- fakeDatabase,
- this,
- api = fakeApi
- )
- assertEquals(mockAndroidVersions, repository.loadAndStoreRemoteAndroidVersions())
- }
-
- @Test
- fun `loadRecentAndroidVersions() should continue to load and store android versions when calling scope gets cancelled`() = runTest {
- val fakeDatabase = FakeDatabase()
- val fakeApi = FakeApi()
- val applicationScope = this
- val repository = AndroidVersionRepository(
- fakeDatabase,
- applicationScope,
- api = fakeApi
- )
-
- // Sharing the testScheduler with the applicationScope is important!
- val viewModelScope = TestScope(this.testScheduler)
- val job = viewModelScope.launch {
- repository.loadAndStoreRemoteAndroidVersions()
- }
-
- // execute coroutine until delay(1) in the fakeApi
- applicationScope.runCurrent()
-
- // Check if nothing is inserted into the db before we cancel the scope
- assertEquals(false, fakeDatabase.insertedIntoDb)
-
- // Cancel the scope and check if it was indeed cancelled
- viewModelScope.cancel()
- assertEquals(true, job.isCancelled)
-
- // continue coroutine execution after delay(1) in the fakeApi
- applicationScope.advanceTimeBy(1)
- applicationScope.runCurrent()
-
- assertEquals(true, fakeDatabase.insertedIntoDb)
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/FakeApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/FakeApi.kt
deleted file mode 100644
index 9dd28bc2..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/FakeApi.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase14
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-
-class FakeApi : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(1)
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/FakeDatabase.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/FakeDatabase.kt
deleted file mode 100644
index 99e1f815..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase14/FakeDatabase.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase14
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-
-class FakeDatabase : AndroidVersionDao {
-
- var insertedIntoDb = false
-
- override suspend fun getAndroidVersions(): List {
- return mockAndroidVersions.mapToEntityList()
- }
-
- override suspend fun insert(androidVersionEntity: AndroidVersionEntity) {
- insertedIntoDb = true
- }
-
- override suspend fun clear() {}
-
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeFeaturesErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeFeaturesErrorApi.kt
deleted file mode 100644
index e0c4c13a..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeFeaturesErrorApi.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeFeaturesErrorApi : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeSuccessApi.kt
deleted file mode 100644
index 936f8956..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeSuccessApi.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-
-class FakeSuccessApi : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeVersionsErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeVersionsErrorApi.kt
deleted file mode 100644
index 10e07482..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/FakeVersionsErrorApi.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeVersionsErrorApi : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModelTest.kt
deleted file mode 100644
index 476302e4..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/Perform2SequentialNetworkRequestsViewModelTest.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesAndroid10
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class Perform2SequentialNetworkRequestsViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `should return Success when both network requests are successful`() = runTest {
- val fakeApi = FakeSuccessApi()
- val viewModel = Perform2SequentialNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.perform2SequentialNetworkRequest()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(mockVersionFeaturesAndroid10)
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `should return Error when first network requests fails`() = runTest {
- val fakeApi = FakeVersionsErrorApi()
- val viewModel = Perform2SequentialNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.perform2SequentialNetworkRequest()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `should return Error when second network requests fails`() = runTest {
- val fakeApi = FakeFeaturesErrorApi()
- val viewModel = Perform2SequentialNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.perform2SequentialNetworkRequest()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- private fun Perform2SequentialNetworkRequestsViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeFeaturesErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeFeaturesErrorApi.kt
deleted file mode 100644
index cd01c334..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeFeaturesErrorApi.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2.callbacks
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import retrofit2.Call
-import retrofit2.mock.Calls
-import java.io.IOException
-
-class FakeFeaturesErrorApi : CallbackMockApi {
-
- override fun getRecentAndroidVersions(): Call> {
- return Calls.response(mockAndroidVersions)
- }
-
- override fun getAndroidVersionFeatures(apiLevel: Int): Call {
- return Calls.failure(IOException())
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeSuccessApi.kt
deleted file mode 100644
index acadabc5..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeSuccessApi.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2.callbacks
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import retrofit2.Call
-import retrofit2.mock.Calls
-
-class FakeSuccessApi : CallbackMockApi {
-
- override fun getRecentAndroidVersions(): Call> {
- return Calls.response(mockAndroidVersions)
- }
-
- override fun getAndroidVersionFeatures(apiLevel: Int): Call {
- val featureMocks = when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- return Calls.response(featureMocks)
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeVersionsErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeVersionsErrorApi.kt
deleted file mode 100644
index acbd8aff..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/FakeVersionsErrorApi.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2.callbacks
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import retrofit2.Call
-import retrofit2.mock.Calls
-import java.io.IOException
-
-class FakeVersionsErrorApi : CallbackMockApi {
-
- override fun getRecentAndroidVersions(): Call> {
- return Calls.response(mockAndroidVersions)
- }
-
- override fun getAndroidVersionFeatures(apiLevel: Int): Call {
- return Calls.failure(IOException())
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModelTest.kt
deleted file mode 100644
index 4a88f60e..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase2/callbacks/SequentialNetworkRequestsCallbacksViewModelTest.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase2.callbacks
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesAndroid10
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-class SequentialNetworkRequestsCallbacksViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- private val receivedUiStates: MutableList =
- arrayListOf()
-
- @Test
- fun `should return Success when both network requests are successful`() {
- val fakeApi = FakeSuccessApi()
- val viewModel =
- SequentialNetworkRequestsCallbacksViewModel(
- fakeApi
- )
-
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.perform2SequentialNetworkRequest()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(mockVersionFeaturesAndroid10)
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `should return Error when first network request (recent-android-versions) fails`() {
- val fakeApi = FakeVersionsErrorApi()
- val viewModel =
- SequentialNetworkRequestsCallbacksViewModel(
- fakeApi
- )
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.perform2SequentialNetworkRequest()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `should return Error when second network requests (android-version-features) fails`() {
- val fakeApi = FakeFeaturesErrorApi()
- val viewModel =
- SequentialNetworkRequestsCallbacksViewModel(
- fakeApi
- )
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.perform2SequentialNetworkRequest()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- private fun SequentialNetworkRequestsCallbacksViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/FakeErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/FakeErrorApi.kt
deleted file mode 100644
index b0fbb361..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/FakeErrorApi.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase3
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeErrorApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- throw EndpointShouldNotBeCalledException()
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- delay(responseDelay)
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/FakeSuccessApi.kt
deleted file mode 100644
index b1dd16ee..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/FakeSuccessApi.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase3
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-
-class FakeSuccessApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- throw EndpointShouldNotBeCalledException()
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- delay(responseDelay)
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModelTest.kt
deleted file mode 100644
index 07bfd067..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase3/PerformNetworkRequestsConcurrentlyViewModelTest.kt
+++ /dev/null
@@ -1,129 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase3
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesAndroid10
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesOreo
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesPie
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.currentTime
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class PerformNetworkRequestsConcurrentlyViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `performNetworkRequestsSequentially should return data after 3 times the response delay`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = PerformNetworkRequestsConcurrentlyViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsSequentially()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(
- listOf(
- mockVersionFeaturesOreo,
- mockVersionFeaturesPie,
- mockVersionFeaturesAndroid10
- )
- )
- ),
- receivedUiStates
- )
-
- // Verify that requests actually got executed sequentially and it took
- // 3000ms to receive all data
- Assert.assertEquals(
- 3000,
- currentTime
- )
- }
-
- @Test
- fun `performNetworkRequestsConcurrently should return data after the response delay`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = PerformNetworkRequestsConcurrentlyViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsConcurrently()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(
- listOf(
- mockVersionFeaturesOreo,
- mockVersionFeaturesPie,
- mockVersionFeaturesAndroid10
- )
- )
- ),
- receivedUiStates
- )
-
- // Verify that requests actually got executed concurrently within 1000ms
- Assert.assertEquals(
- 1000,
- currentTime
- )
- }
-
- @Test
- fun `performNetworkRequestsConcurrently should return Error when network request fails`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeErrorApi(responseDelay)
- val viewModel = PerformNetworkRequestsConcurrentlyViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsConcurrently()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- private fun PerformNetworkRequestsConcurrentlyViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeFeaturesErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeFeaturesErrorApi.kt
deleted file mode 100644
index 43361ba7..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeFeaturesErrorApi.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase4
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import kotlinx.coroutines.delay
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeFeaturesErrorApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(responseDelay)
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- delay(responseDelay)
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeSuccessApi.kt
deleted file mode 100644
index c77d99dc..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeSuccessApi.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase4
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import kotlinx.coroutines.delay
-
-class FakeSuccessApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(1000)
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- delay(responseDelay)
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeVersionsErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeVersionsErrorApi.kt
deleted file mode 100644
index bcb12301..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/FakeVersionsErrorApi.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase4
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeVersionsErrorApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(responseDelay)
- throw throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModelTest.kt
deleted file mode 100644
index d21c1fe7..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase4/VariableAmountOfNetworkRequestsViewModelTest.kt
+++ /dev/null
@@ -1,195 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase4
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesAndroid10
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesOreo
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockVersionFeaturesPie
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.currentTime
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class VariableAmountOfNetworkRequestsViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `performNetworkRequestsSequentially() should return Success UiState on successful network requests after 4000ms`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = VariableAmountOfNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsSequentially()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(
- listOf(
- mockVersionFeaturesOreo,
- mockVersionFeaturesPie,
- mockVersionFeaturesAndroid10
- )
- )
- ),
- receivedUiStates
- )
-
- Assert.assertEquals(
- 4000,
- currentTime
- )
- }
-
- @Test
- fun `performNetworkRequestsSequentially() should return Error UiState on unsuccessful recent-android-versions network request`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeVersionsErrorApi(responseDelay)
- val viewModel = VariableAmountOfNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsSequentially()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `performNetworkRequestsSequentially() should return Error UiState on unsuccessful android-version-features network request`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeFeaturesErrorApi(responseDelay)
- val viewModel = VariableAmountOfNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsSequentially()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `performNetworkRequestsConcurrently() should return Success UiState on successful network requests after 2000ms`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = VariableAmountOfNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsConcurrently()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(
- listOf(
- mockVersionFeaturesOreo,
- mockVersionFeaturesPie,
- mockVersionFeaturesAndroid10
- )
- )
- ),
- receivedUiStates
- )
-
- Assert.assertEquals(
- 2000,
- currentTime
- )
- }
-
- @Test
- fun `performNetworkRequestsConcurrently() should return Error UiState on unsuccessful recent-android-versions network request`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeVersionsErrorApi(responseDelay)
- val viewModel = VariableAmountOfNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsConcurrently()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `performNetworkRequestsConcurrently() should return Error UiState on unsuccessful android-version-features network request`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeFeaturesErrorApi(responseDelay)
- val viewModel = VariableAmountOfNetworkRequestsViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequestsConcurrently()
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
- }
-
- private fun VariableAmountOfNetworkRequestsViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/FakeSuccessApi.kt
deleted file mode 100644
index 163efd07..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/FakeSuccessApi.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase5
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import kotlinx.coroutines.delay
-
-class FakeSuccessApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(1000)
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- delay(responseDelay)
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/FakeVersionsErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/FakeVersionsErrorApi.kt
deleted file mode 100644
index deab526a..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/FakeVersionsErrorApi.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase5
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeVersionsErrorApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(responseDelay)
- throw throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModelTest.kt
deleted file mode 100644
index 295b88d6..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase5/NetworkRequestWithTimeoutViewModelTest.kt
+++ /dev/null
@@ -1,104 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase5
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class NetworkRequestWithTimeoutViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `performNetworkRequest() should return Success UiState on successful network request within timeout`() =
- runTest {
- val responseDelay = 1000L
- val timeout = 1001L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = NetworkRequestWithTimeoutViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequest(timeout)
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(mockAndroidVersions)
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `performNetworkRequest() should return Error UiState with timeout error message if timeout gets exceeded`() =
- runTest {
- val responseDelay = 1000L
- val timeout = 999L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = NetworkRequestWithTimeoutViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequest(timeout)
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request timed out!")
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `performNetworkRequest() should return Error UiState on unsuccessful network response`() =
- runTest {
- val responseDelay = 1000L
- val timeout = 1001L
- val fakeApi = FakeVersionsErrorApi(responseDelay)
- val viewModel = NetworkRequestWithTimeoutViewModel(fakeApi)
- viewModel.observe()
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequest(timeout)
-
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed!")
- ),
- receivedUiStates
- )
- }
-
- private fun NetworkRequestWithTimeoutViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeSuccessApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeSuccessApi.kt
deleted file mode 100644
index 24d85e4e..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeSuccessApi.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase6
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.*
-import kotlinx.coroutines.delay
-
-class FakeSuccessApi(private val responseDelay: Long) : MockApi {
-
- override suspend fun getRecentAndroidVersions(): List {
- delay(1000)
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- delay(responseDelay)
- return when (apiLevel) {
- 27 -> mockVersionFeaturesOreo
- 28 -> mockVersionFeaturesPie
- 29 -> mockVersionFeaturesAndroid10
- else -> throw IllegalArgumentException("apiLevel not found")
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeSuccessOnThirdAttemptApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeSuccessOnThirdAttemptApi.kt
deleted file mode 100644
index 74c91038..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeSuccessOnThirdAttemptApi.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase6
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-import java.io.IOException
-
-class FakeSuccessOnThirdAttemptApi(private val responseDelay: Long) : MockApi {
-
- var requestCount = 0
-
- override suspend fun getRecentAndroidVersions(): List {
- requestCount++
- delay(responseDelay)
- if (requestCount < 3) {
- throw IOException()
- }
- return mockAndroidVersions
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeVersionsErrorApi.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeVersionsErrorApi.kt
deleted file mode 100644
index 704d0199..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/FakeVersionsErrorApi.kt
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase6
-
-import com.lukaslechner.coroutineusecasesonandroid.mock.AndroidVersion
-import com.lukaslechner.coroutineusecasesonandroid.mock.MockApi
-import com.lukaslechner.coroutineusecasesonandroid.mock.VersionFeatures
-import com.lukaslechner.coroutineusecasesonandroid.utils.EndpointShouldNotBeCalledException
-import kotlinx.coroutines.delay
-import okhttp3.MediaType
-import okhttp3.ResponseBody
-import retrofit2.HttpException
-import retrofit2.Response
-
-class FakeVersionsErrorApi(private val responseDelay: Long) : MockApi {
-
- var requestCount = 0
-
- override suspend fun getRecentAndroidVersions(): List {
- requestCount++
- delay(responseDelay)
- throw throw HttpException(
- Response.error>(
- 500,
- ResponseBody.create(MediaType.parse("application/json"), "")
- )
- )
- }
-
- override suspend fun getAndroidVersionFeatures(apiLevel: Int): VersionFeatures {
- throw EndpointShouldNotBeCalledException()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModelTest.kt
deleted file mode 100644
index e15e1a36..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/coroutines/usecase6/RetryNetworkRequestViewModelTest.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.coroutines.usecase6
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.mock.mockAndroidVersions
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.advanceUntilIdle
-import kotlinx.coroutines.test.currentTime
-import kotlinx.coroutines.test.runTest
-import org.junit.Assert
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-@ExperimentalCoroutinesApi
-class RetryNetworkRequestViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `performSingleNetworkRequest() should return Success UiState on successful network response`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeSuccessApi(responseDelay)
- val viewModel = RetryNetworkRequestViewModel(fakeApi).apply {
- observe()
- }
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequest()
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(mockAndroidVersions)
- ),
- receivedUiStates
- )
- }
-
- @Test
- fun `performSingleNetworkRequest() should retry network request two times`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeSuccessOnThirdAttemptApi(responseDelay)
- val viewModel = RetryNetworkRequestViewModel(fakeApi).apply {
- observe()
- }
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequest()
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Success(mockAndroidVersions)
- ),
- receivedUiStates
- )
-
- Assert.assertEquals(
- 3,
- fakeApi.requestCount
- )
-
- // 3*1000 (Request delays) + 100 (initial delay) + 200 (second delay)
- Assert.assertEquals(
- 3300,
- currentTime
- )
- }
-
- @Test
- fun `performSingleNetworkRequest() should return Error UiState on 3 unsuccessful network responses`() =
- runTest {
- val responseDelay = 1000L
- val fakeApi = FakeVersionsErrorApi(responseDelay)
- val viewModel = RetryNetworkRequestViewModel(fakeApi).apply {
- observe()
- }
-
- Assert.assertTrue(receivedUiStates.isEmpty())
-
- viewModel.performNetworkRequest()
- advanceUntilIdle()
-
- Assert.assertEquals(
- listOf(
- UiState.Loading,
- UiState.Error("Network Request failed")
- ),
- receivedUiStates
- )
-
- Assert.assertEquals(
- 3,
- fakeApi.requestCount
- )
-
- // 3*1000 response delays + 100 (initial delay) + 200 (second delay)
- Assert.assertEquals(
- 3300,
- currentTime
- )
- }
-
- private fun RetryNetworkRequestViewModel.observe() {
- uiState().observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FakeStockPriceDataSource.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FakeStockPriceDataSource.kt
deleted file mode 100644
index 5bcbbac9..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FakeStockPriceDataSource.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase1
-
-import com.lukaslechner.coroutineusecasesonandroid.usecases.flow.mock.Stock
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.asSharedFlow
-
-class FakeStockPriceDataSource : StockPriceDataSource {
-
- private val sharedFlow = MutableSharedFlow>()
-
- suspend fun emit(stockList: List) {
- sharedFlow.emit(stockList)
- }
-
- override val latestStockList: Flow> = sharedFlow.asSharedFlow()
-
-}
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModelTest.kt
deleted file mode 100644
index 8bf71c4c..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/FlowUseCase1ViewModelTest.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase1
-
-import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.TestRule
-
-class FlowUseCase1ViewModelTest {
-
- @get:Rule
- val testInstantTaskExecutorRule: TestRule = InstantTaskExecutorRule()
-
- @OptIn(ExperimentalCoroutinesApi::class)
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- private val receivedUiStates = mutableListOf()
-
- @Test
- fun `should return success UI States with values of fakeDataSource`() = runTest {
-
- val fakeDataSource = FakeStockPriceDataSource()
- val viewModel = FlowUseCase1ViewModel(fakeDataSource)
- observeViewModel(viewModel)
-
- assertEquals(UiState.Loading, receivedUiStates[0])
- assertEquals(1, receivedUiStates.size)
-
- fakeDataSource.emit(listOf(googleStock, appleStock))
- assertEquals(UiState.Success(listOf(googleStock, appleStock)), receivedUiStates[1])
- assertEquals(2, receivedUiStates.size)
-
- fakeDataSource.emit(listOf(googleStock))
- assertEquals(UiState.Success(listOf(googleStock)), receivedUiStates[2])
- assertEquals(3, receivedUiStates.size)
- }
-
- private fun observeViewModel(viewModel: FlowUseCase1ViewModel) {
- viewModel.currentStockPriceAsLiveData.observeForever { uiState ->
- if (uiState != null) {
- receivedUiStates.add(uiState)
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/TestData.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/TestData.kt
deleted file mode 100644
index 32e2a66f..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase1/TestData.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase1
-
-import com.lukaslechner.coroutineusecasesonandroid.usecases.flow.mock.Stock
-
-val appleStock = Stock(
- rank = 1,
- name = "Apple",
- symbol = "AAPL",
- marketCap = 1.0f,
- country = "United Stated",
- currentPrice = 1.0f
-)
-
-val googleStock = Stock(
- rank = 4,
- name = "Alphabet",
- symbol = "GOOG",
- marketCap = 2.0f,
- country = "United Stated",
- currentPrice = 2.0f
-)
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FakeStockPriceDataSource.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FakeStockPriceDataSource.kt
deleted file mode 100644
index 32c11197..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FakeStockPriceDataSource.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase4
-
-import com.lukaslechner.coroutineusecasesonandroid.usecases.flow.mock.Stock
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.asSharedFlow
-
-class FakeStockPriceDataSource : StockPriceDataSource {
-
- private val sharedFlow = MutableSharedFlow>()
-
- suspend fun emit(stockList: List) {
- sharedFlow.emit(stockList)
- }
-
- override val latestStockList: Flow> = sharedFlow.asSharedFlow()
-
-}
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModelTest.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModelTest.kt
deleted file mode 100644
index 6837cef9..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/usecases/flow/usecase4/FlowUseCase4ViewModelTest.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase4
-
-import com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase1.appleStock
-import com.lukaslechner.coroutineusecasesonandroid.usecases.flow.usecase1.googleStock
-import com.lukaslechner.coroutineusecasesonandroid.utils.ReplaceMainDispatcherRule
-import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Rule
-import org.junit.Test
-
-class FlowUseCase4ViewModelTest {
-
- @OptIn(ExperimentalCoroutinesApi::class)
- @get: Rule
- val replaceMainDispatcherRule = ReplaceMainDispatcherRule()
-
- @Test
- fun `should collect loading and success ui states on successful emissions`() = runTest {
-
- val fakeStockPriceDataSource = FakeStockPriceDataSource()
- val viewModel = FlowUseCase4ViewModel(fakeStockPriceDataSource)
-
- val collectJob =
- launch(UnconfinedTestDispatcher()) {
- viewModel.currentStockPriceAsFlow.collect()
- }
-
- assertEquals(
- UiState.Loading,
- viewModel.currentStockPriceAsFlow.value
- )
-
- fakeStockPriceDataSource.emit(
- listOf(
- googleStock,
- appleStock
- )
- )
-
- assertEquals(
- UiState.Success(
- listOf(
- googleStock,
- appleStock
- )
- ),
- viewModel.currentStockPriceAsFlow.value
- )
-
- fakeStockPriceDataSource.emit(listOf(googleStock))
-
- assertEquals(
- UiState.Success(
- listOf(
- googleStock
- )
- ),
- viewModel.currentStockPriceAsFlow.value
- )
-
- collectJob.cancel()
- }
-}
\ No newline at end of file
diff --git a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/utils/EndpointShouldNotBeCalledException.kt b/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/utils/EndpointShouldNotBeCalledException.kt
deleted file mode 100644
index f6c60b0a..00000000
--- a/app/src/test/java/com/lukaslechner/coroutineusecasesonandroid/utils/EndpointShouldNotBeCalledException.kt
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.lukaslechner.coroutineusecasesonandroid.utils
-
-class EndpointShouldNotBeCalledException : Throwable()
\ No newline at end of file