• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Unleash / unleash-android / 10077204014

24 Jul 2024 01:04PM UTC coverage: 78.922% (+2.4%) from 76.546%
10077204014

Pull #66

github

web-flow
Merge 6f0bba963 into 812f882d3
Pull Request #66: chore: several test cases in 3 commits

197 of 280 branches covered (70.36%)

Branch coverage included in aggregate %.

6 of 6 new or added lines in 2 files covered. (100.0%)

6 existing lines in 1 file now uncovered.

608 of 740 relevant lines covered (82.16%)

5.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.5
/unleashandroidsdk/src/main/java/io/getunleash/android/backup/LocalBackup.kt
1
package io.getunleash.android.backup
2

3
import android.util.Log
4
import com.fasterxml.jackson.module.kotlin.readValue
5
import io.getunleash.android.data.Parser
6
import io.getunleash.android.data.Toggle
7
import io.getunleash.android.data.UnleashContext
8
import io.getunleash.android.data.UnleashState
9
import io.getunleash.android.unleashScope
10
import kotlinx.coroutines.Dispatchers
11
import kotlinx.coroutines.flow.Flow
12
import kotlinx.coroutines.launch
13
import kotlinx.coroutines.withContext
14
import java.io.File
15

16
private data class BackupState(val contextId: String, val toggles: Map<String, Toggle>)
15✔
17

18
/**
19
 * Local backup of the last state of the Unleash SDK.
20
 *
21
 * Because it only keeps the last state, it also saves the context id, and uses it to verify the context
22
 * is the same when loading the state from disc.
23
 */
24
class LocalBackup(
3✔
25
    private val localDir: File
3✔
26
) {
27
    companion object {
28
        private const val TAG = "LocalBackup"
29
        internal const val STATE_BACKUP_FILE = "unleash_state.json"
30
    }
31

32
    private var lastContext: UnleashContext? = null
33

34
    fun subscribeTo(state: Flow<UnleashState>) {
35
        unleashScope.launch {
14✔
36
            withContext(Dispatchers.IO) {
17✔
37
                state.collect {
14✔
38
                    if (it.context != lastContext) {
7!
39
                        lastContext = it.context
5✔
40
                        writeToDisc(it)
5✔
41
                    } else {
UNCOV
42
                        Log.d(TAG, "Context unchanged, not writing to disc")
×
43
                    }
44
                }
2✔
45
            }
×
UNCOV
46
        }
×
47
    }
1✔
48

49
    private fun writeToDisc(state: UnleashState) {
50
        try {
1✔
51
            // write only the last state
52
            val contextBackup = File(localDir.absolutePath, STATE_BACKUP_FILE)
8✔
53
            contextBackup.writeBytes(Parser.jackson.writeValueAsBytes(BackupState(id(state.context), state.toggles)))
17✔
54
            Log.d(TAG, "Written state to ${contextBackup.absolutePath}")
13✔
55
        } catch (e: Exception) {
×
UNCOV
56
            Log.i(TAG, "Error writing to disc", e)
×
57
        }
58
    }
1✔
59

60
    fun loadFromDisc(context: UnleashContext): UnleashState? {
61
        val stateBackup = File(localDir.absolutePath, STATE_BACKUP_FILE)
8✔
62
        try {
1✔
63
            if (stateBackup.exists()) {
3!
64
                val backupState = Parser.jackson.readValue<BackupState>(stateBackup.readBytes())
10✔
65
                if (backupState.contextId != id(context)) {
7✔
66
                    Log.i(TAG, "Context id mismatch, ignoring backup for context id ${backupState.contextId}")
12✔
67
                    return null
2✔
68
                }
69
                return UnleashState(context, backupState.toggles)
7✔
70
            } else {
UNCOV
71
                Log.d(TAG, "No backup found at ${stateBackup.absolutePath}")
×
72
            }
73
        } catch (e: Exception) {
×
UNCOV
74
            Log.w(TAG, "Error loading from disc ${stateBackup.absolutePath}", e)
×
75
        }
UNCOV
76
        return null
×
77
    }
78

79
    private fun id(context: UnleashContext): String {
80
        return context.hashCode().toString()
4✔
81
    }
82
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc