Add confirmation dialog and tests

This commit is contained in:
Lucas Lima 2020-07-09 23:59:29 -03:00
parent 1e80386d10
commit 24d6c152dc
No known key found for this signature in database
GPG key ID: C5EEF4C30BFBF8D7
5 changed files with 149 additions and 43 deletions

View file

@ -4,11 +4,13 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import dagger.hilt.android.AndroidEntryPoint
import dev.lucasnlm.antimine.R
import dev.lucasnlm.antimine.common.level.repository.IStatsRepository
import dev.lucasnlm.antimine.stats.model.StatsModel
import dev.lucasnlm.antimine.stats.viewmodel.StatsViewModel
import kotlinx.android.synthetic.main.activity_stats.*
import kotlinx.coroutines.GlobalScope
@ -24,19 +26,12 @@ class StatsActivity : AppCompatActivity(R.layout.activity_stats) {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
refreshStats(StatsViewModel.emptyStats)
viewModel.statsObserver.observe(
this,
Observer {
minesCount.text = it.mines.toString()
totalTime.text = formatTime(it.duration)
averageTime.text = formatTime(it.averageDuration)
totalGames.text = it.totalGames.toString()
performance.text = formatPercentage(100.0 * it.victory / it.totalGames)
openAreas.text = it.openArea.toString()
victory.text = it.victory.toString()
defeat.text = (it.totalGames - it.victory).toString()
invalidateOptionsMenu()
refreshStats(it)
}
)
@ -45,6 +40,31 @@ class StatsActivity : AppCompatActivity(R.layout.activity_stats) {
}
}
private fun refreshStats(stats: StatsModel) {
if (stats.totalGames > 0) {
minesCount.text = stats.mines.toString()
totalTime.text = formatTime(stats.duration)
averageTime.text = formatTime(stats.averageDuration)
totalGames.text = stats.totalGames.toString()
performance.text = formatPercentage(100.0 * stats.victory / stats.totalGames)
openAreas.text = stats.openArea.toString()
victory.text = stats.victory.toString()
defeat.text = (stats.totalGames - stats.victory).toString()
} else {
val emptyText = "-"
totalGames.text = "0"
minesCount.text = emptyText
totalTime.text = emptyText
averageTime.text = emptyText
performance.text = emptyText
openAreas.text = emptyText
victory.text = emptyText
defeat.text = emptyText
}
invalidateOptionsMenu()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
viewModel.statsObserver.value?.let {
if (it.totalGames > 0) {
@ -56,15 +76,27 @@ class StatsActivity : AppCompatActivity(R.layout.activity_stats) {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return if (item.itemId == R.id.delete) {
GlobalScope.launch {
viewModel.deleteAll()
}
confirmAndDelete()
true
} else {
super.onOptionsItemSelected(item)
}
}
private fun confirmAndDelete() {
AlertDialog.Builder(this)
.setTitle(R.string.are_you_sure)
.setMessage(R.string.delete_all_message)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.delete_all) { _, _ ->
GlobalScope.launch {
viewModel.deleteAll()
}
}
.show()
}
companion object {
private fun formatPercentage(value: Double) =
String.format("%.2f%%", value)

View file

@ -54,6 +54,6 @@ class StatsViewModel @ViewModelInject constructor(
}
companion object {
private val emptyStats = StatsModel(0, 0, 0, 0, 0, 0)
val emptyStats = StatsModel(0, 0, 0, 0, 0, 0)
}
}

View file

@ -2,9 +2,13 @@ package dev.lucasnlm.antimine.stats.viewmodel
import dev.lucasnlm.antimine.common.level.database.models.Stats
import dev.lucasnlm.antimine.common.level.repository.MemoryStatsRepository
import dev.lucasnlm.antimine.core.preferences.IPreferencesRepository
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
@ExperimentalCoroutinesApi
@ -14,63 +18,132 @@ class StatsViewModelTest {
Stats(1, 1200, 24, 0, 10, 10, 20)
)
private val prefsRepository: IPreferencesRepository = mockk()
@Before
fun setup() {
every { prefsRepository.getStatsBase() } returns 0
}
@Test
fun testStatsTotalGames() = runBlockingTest {
val viewModel = StatsViewModel()
val statsModel = viewModel.getStatsModel(MemoryStatsRepository(listOfStats.toMutableList()))
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(2, statsModel?.totalGames)
}
val emptyStatsModel = viewModel.getStatsModel(MemoryStatsRepository())
assertEquals(0, emptyStatsModel?.totalGames)
@Test
fun testStatsTotalGamesWithBase() = runBlockingTest {
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
every { prefsRepository.getStatsBase() } returns 0
val statsModelBase0 = viewModel.getStatsModel()
assertEquals(2, statsModelBase0?.totalGames)
every { prefsRepository.getStatsBase() } returns 1
val statsModelBase1 = viewModel.getStatsModel()
assertEquals(1, statsModelBase1?.totalGames)
every { prefsRepository.getStatsBase() } returns 2
val statsModelBase2 = viewModel.getStatsModel()
assertEquals(0, statsModelBase2?.totalGames)
}
@Test
fun testStatsTotalGamesEmpty() = runBlockingTest {
val repository = MemoryStatsRepository(mutableListOf())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(0, statsModel?.totalGames)
}
@Test
fun testStatsDuration() = runBlockingTest {
val viewModel = StatsViewModel()
val statsModel = viewModel.getStatsModel(MemoryStatsRepository(listOfStats.toMutableList()))
assertEquals(2200L, statsModel?.duration)
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
val emptyStatsModel = viewModel.getStatsModel(MemoryStatsRepository())
assertEquals(0L, emptyStatsModel?.duration)
assertEquals(2200L, statsModel?.duration)
}
@Test
fun testStatsDurationEmpty() = runBlockingTest {
val repository = MemoryStatsRepository(mutableListOf())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(0L, statsModel?.duration)
}
@Test
fun testStatsAverageDuration() = runBlockingTest {
val viewModel = StatsViewModel()
val statsModel = viewModel.getStatsModel(MemoryStatsRepository(listOfStats.toMutableList()))
assertEquals(1100L, statsModel?.averageDuration)
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
val emptyStatsModel = viewModel.getStatsModel(MemoryStatsRepository(mutableListOf()))
assertEquals(0L, emptyStatsModel?.averageDuration)
assertEquals(1100L, statsModel?.averageDuration)
}
@Test
fun testStatsAverageDurationEmpty() = runBlockingTest {
val repository = MemoryStatsRepository(mutableListOf())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(0L, statsModel?.averageDuration)
}
@Test
fun testStatsMines() = runBlockingTest {
val viewModel = StatsViewModel()
val statsModel = viewModel.getStatsModel(MemoryStatsRepository(listOfStats.toMutableList()))
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(34, statsModel?.mines)
}
val emptyStatsModel = viewModel.getStatsModel(MemoryStatsRepository(mutableListOf()))
assertEquals(0, emptyStatsModel?.mines)
@Test
fun testStatsMinesEmpty() = runBlockingTest {
val repository = MemoryStatsRepository(mutableListOf())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(0, statsModel?.mines)
}
@Test
fun testVictory() = runBlockingTest {
val viewModel = StatsViewModel()
val statsModel = viewModel.getStatsModel(MemoryStatsRepository(listOfStats.toMutableList()))
assertEquals(1, statsModel?.victory)
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
val emptyStatsModel = viewModel.getStatsModel(MemoryStatsRepository(mutableListOf()))
assertEquals(0, emptyStatsModel?.victory)
assertEquals(1, statsModel?.victory)
}
@Test
fun testVictoryEmpty() = runBlockingTest {
val repository = MemoryStatsRepository(mutableListOf())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(0, statsModel?.victory)
}
@Test
fun testOpenArea() = runBlockingTest {
val viewModel = StatsViewModel()
val statsModel = viewModel.getStatsModel(MemoryStatsRepository(listOfStats.toMutableList()))
assertEquals(110, statsModel?.openArea)
val repository = MemoryStatsRepository(listOfStats.toMutableList())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
val emptyStatsModel = viewModel.getStatsModel(MemoryStatsRepository(mutableListOf()))
assertEquals(0, emptyStatsModel?.openArea)
assertEquals(110, statsModel?.openArea)
}
@Test
fun testOpenAreaEmpty() = runBlockingTest {
val repository = MemoryStatsRepository(mutableListOf())
val viewModel = StatsViewModel(repository, prefsRepository)
val statsModel = viewModel.getStatsModel()
assertEquals(0, statsModel?.openArea)
}
}

View file

@ -23,7 +23,7 @@ class StatsRepository(
class MemoryStatsRepository(
private val memoryStats: MutableList<Stats> = mutableListOf()
) : IStatsRepository {
override suspend fun getAllStats(minId: Int): List<Stats> = memoryStats.toList()
override suspend fun getAllStats(minId: Int): List<Stats> = memoryStats.filter { it.uid >= minId }
override suspend fun addStats(stats: Stats): Long? {
memoryStats.add(stats)

View file

@ -87,6 +87,7 @@
<string name="open_menu">Open Menu</string>
<string name="close_menu">Close Menu</string>
<string name="delete_all">Delete all</string>
<string name="delete_all_message">Delete all events permanently.</string>
<string name="all_mines_disabled">All mines were disabled.</string>
<string name="desc_convered_area">Covered area</string>
<string name="desc_marked_area">Marked area</string>