diff --git a/android/DartsScorecard/app/build.gradle b/android/DartsScorecard/app/build.gradle
index 591dcb24..901cdeac 100644
--- a/android/DartsScorecard/app/build.gradle
+++ b/android/DartsScorecard/app/build.gradle
@@ -42,7 +42,6 @@ dependencies {
implementation "com.android.support:appcompat-v7:$support"
implementation "com.android.support:design:$support"
implementation "com.android.support.constraint:constraint-layout:$constraint"
- implementation "com.google.firebase:firebase-core:$firebase"
implementation "com.google.android.gms:play-services-ads:$firebase"
implementation "android.arch.lifecycle:extensions:$architectureComponents"
implementation "android.arch.persistence.room:runtime:$architectureComponents"
diff --git a/android/DartsScorecard/app/src/main/AndroidManifest.xml b/android/DartsScorecard/app/src/main/AndroidManifest.xml
index 86f68e47..83829d19 100644
--- a/android/DartsScorecard/app/src/main/AndroidManifest.xml
+++ b/android/DartsScorecard/app/src/main/AndroidManifest.xml
@@ -25,8 +25,7 @@
android:parentActivityName=".launch.LaunchActivity" />
+ android:windowSoftInputMode="adjustResize" />
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/base/widget/MaxHeightRecyclerView.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/base/widget/MaxHeightRecyclerView.kt
new file mode 100644
index 00000000..f6d2371d
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/base/widget/MaxHeightRecyclerView.kt
@@ -0,0 +1,20 @@
+package nl.entreco.dartsscorecard.base.widget
+
+import android.content.Context
+import android.support.v7.widget.RecyclerView
+import android.util.AttributeSet
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+class MaxHeightRecyclerView @JvmOverloads constructor(
+ context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : RecyclerView(context, attrs, defStyleAttr) {
+
+ var maxHeight: Int = 400
+
+ override fun onMeasure(widthSpec: Int, heightSpec: Int) {
+ val height = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST)
+ super.onMeasure(widthSpec, height)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt
index 82ec16dc..34977075 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/application/AppModule.kt
@@ -5,8 +5,8 @@ import dagger.Module
import dagger.Provides
import nl.entreco.dartsscorecard.App
import nl.entreco.dartsscorecard.DscLogger
-import nl.entreco.dartsscorecard.analytics.FirebaseAnalytics
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.analytics.FirebaseAnalytics
+import nl.entreco.data.db.DscDatabase
import nl.entreco.domain.Analytics
import nl.entreco.domain.Logger
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt
index 92f671b1..a1b655f3 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/play/Play01Component.kt
@@ -4,7 +4,8 @@ import dagger.Subcomponent
import nl.entreco.dartsscorecard.play.Play01ViewModel
import nl.entreco.dartsscorecard.play.input.InputViewModel
import nl.entreco.dartsscorecard.play.score.ScoreViewModel
-import nl.entreco.domain.play.usecase.GetFinishUsecase
+import nl.entreco.dartsscorecard.play.stats.MatchStatViewModel
+import nl.entreco.domain.play.finish.GetFinishUsecase
/**
* Created by Entreco on 14/11/2017.
@@ -15,5 +16,6 @@ interface Play01Component {
fun viewModel(): Play01ViewModel
fun scoreViewModel(): ScoreViewModel
fun inputViewModel(): InputViewModel
+ fun statViewModel(): MatchStatViewModel
fun finishUsecase(): GetFinishUsecase
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt
index 45ac58a5..6bad789c 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/setup/Setup01Module.kt
@@ -6,7 +6,7 @@ import dagger.Provides
import nl.entreco.dartsscorecard.setup.Setup01Activity
import nl.entreco.dartsscorecard.setup.Setup01Navigator
import nl.entreco.dartsscorecard.setup.players.PlayerEditor
-import nl.entreco.data.setup.repository.SharedPreferenceRepo
+import nl.entreco.data.prefs.SharedPreferenceRepo
import nl.entreco.domain.repository.PreferenceRepository
/**
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt
index 622cbdc1..0d4326bf 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/ViewModelComponent.kt
@@ -10,16 +10,16 @@ import nl.entreco.dartsscorecard.di.setup.EditPlayerComponent
import nl.entreco.dartsscorecard.di.setup.EditPlayerModule
import nl.entreco.dartsscorecard.di.setup.Setup01Component
import nl.entreco.dartsscorecard.di.setup.Setup01Module
-import nl.entreco.dartsscorecard.di.viewmodel.db.GameDbModule
-import nl.entreco.dartsscorecard.di.viewmodel.db.PlayerDbModule
-import nl.entreco.dartsscorecard.di.viewmodel.db.TurnDbModule
+import nl.entreco.dartsscorecard.di.viewmodel.db.*
import nl.entreco.dartsscorecard.di.viewmodel.threading.ThreadingModule
/**
* Created by Entreco on 14/11/2017.
*/
@ActivityScope
-@Subcomponent(modules = [(ViewModelModule::class), (ThreadingModule::class), (GameDbModule::class), (PlayerDbModule::class), (TurnDbModule::class)])
+@Subcomponent(modules = [(ViewModelModule::class), (ThreadingModule::class),
+ (GameDbModule::class), (PlayerDbModule::class), (TurnDbModule::class),
+ (MetaDbModule::class), (StatDbModule::class)])
interface ViewModelComponent {
fun inject(activity: Activity)
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt
index 33b38853..ca8e4bf6 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModule.kt
@@ -3,9 +3,9 @@ package nl.entreco.dartsscorecard.di.viewmodel.db
import dagger.Module
import dagger.Provides
import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.db.game.GameMapper
-import nl.entreco.data.play.repository.LocalGameRepository
+import nl.entreco.data.db.game.LocalGameRepository
import nl.entreco.domain.repository.GameRepository
/**
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModule.kt
new file mode 100644
index 00000000..814f4ede
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModule.kt
@@ -0,0 +1,28 @@
+package nl.entreco.dartsscorecard.di.viewmodel.db
+
+import dagger.Module
+import dagger.Provides
+import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.meta.LocalMetaRepository
+import nl.entreco.data.db.meta.MetaMapper
+import nl.entreco.domain.repository.MetaRepository
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+@Module
+class MetaDbModule {
+
+ @Provides
+ @ActivityScope
+ fun provideMetaMapper(): MetaMapper {
+ return MetaMapper()
+ }
+
+ @Provides
+ @ActivityScope
+ fun provideMetaRepository(db: DscDatabase, mapper: MetaMapper): MetaRepository {
+ return LocalMetaRepository(db, mapper)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt
index 6596a443..ce7d8ed2 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModule.kt
@@ -3,9 +3,9 @@ package nl.entreco.dartsscorecard.di.viewmodel.db
import dagger.Module
import dagger.Provides
import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.player.LocalPlayerRepository
import nl.entreco.data.db.player.PlayerMapper
-import nl.entreco.data.play.repository.LocalPlayerRepository
import nl.entreco.domain.repository.PlayerRepository
/**
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/StatDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/StatDbModule.kt
new file mode 100644
index 00000000..ca9d32e7
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/StatDbModule.kt
@@ -0,0 +1,28 @@
+package nl.entreco.dartsscorecard.di.viewmodel.db
+
+import dagger.Module
+import dagger.Provides
+import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.stats.LocalStatRepository
+import nl.entreco.data.db.stats.StatMapper
+import nl.entreco.domain.repository.StatRepository
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+@Module
+class StatDbModule {
+
+ @Provides
+ @ActivityScope
+ fun provideStatMapper(): StatMapper {
+ return StatMapper()
+ }
+
+ @Provides
+ @ActivityScope
+ fun provideStatRepository(db: DscDatabase, mapper: StatMapper): StatRepository {
+ return LocalStatRepository(db, mapper)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt
index 2e20267a..e99d5515 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModule.kt
@@ -3,9 +3,9 @@ package nl.entreco.dartsscorecard.di.viewmodel.db
import dagger.Module
import dagger.Provides
import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.turn.LocalTurnRepository
import nl.entreco.data.db.turn.TurnMapper
-import nl.entreco.data.play.repository.LocalTurnRepository
import nl.entreco.domain.repository.TurnRepository
/**
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt
index 14f7eb77..f933107b 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModule.kt
@@ -4,10 +4,10 @@ import android.os.Handler
import dagger.Module
import dagger.Provides
import nl.entreco.dartsscorecard.di.viewmodel.ActivityScope
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.BgExecutor
-import nl.entreco.domain.executors.FgExecutor
-import nl.entreco.domain.executors.Foreground
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.BgExecutor
+import nl.entreco.domain.common.executors.FgExecutor
+import nl.entreco.domain.common.executors.Foreground
/**
* Created by Entreco on 17/12/2017.
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt
index 6e30910e..4bc52dad 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchBindings.kt
@@ -2,7 +2,7 @@ package nl.entreco.dartsscorecard.launch
import android.databinding.BindingAdapter
import android.view.View
-import nl.entreco.domain.repository.RetrieveGameRequest
+import nl.entreco.domain.setup.game.CreateGameResponse
/**
* Created by Entreco on 19/12/2017.
@@ -12,8 +12,8 @@ abstract class LaunchBindings {
companion object {
@JvmStatic
@BindingAdapter("resumeGame")
- fun resumeGame(view: View, request: RetrieveGameRequest?) {
- view.animate().alpha(if (request == null) 0.5F else 1.0F).start()
+ fun resumeGame(view: View, response: CreateGameResponse?) {
+ view.animate().alpha(if (response == null) 0.5F else 1.0F).start()
}
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt
index 99202f6a..f4005c30 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/launch/LaunchViewModel.kt
@@ -6,8 +6,8 @@ import nl.entreco.dartsscorecard.base.BaseViewModel
import nl.entreco.dartsscorecard.play.Play01Activity
import nl.entreco.dartsscorecard.setup.Setup01Activity
import nl.entreco.domain.launch.FetchLatestGameResponse
-import nl.entreco.domain.launch.usecase.RetrieveLatestGameUsecase
-import nl.entreco.domain.repository.RetrieveGameRequest
+import nl.entreco.domain.launch.RetrieveLatestGameUsecase
+import nl.entreco.domain.setup.game.CreateGameResponse
import javax.inject.Inject
/**
@@ -15,7 +15,7 @@ import javax.inject.Inject
*/
class LaunchViewModel @Inject constructor(private val retrieveGameUsecase: RetrieveLatestGameUsecase) : BaseViewModel() {
- val resumedGame = ObservableField(null)
+ val resumedGame = ObservableField(null)
fun onNewGamePressed(context: Context) {
Setup01Activity.launch(context)
@@ -35,8 +35,8 @@ class LaunchViewModel @Inject constructor(private val retrieveGameUsecase: Retri
private fun removeGameToResume(): (Throwable) -> Unit = { resumedGame.set(null) }
private fun setGameToResume(): (FetchLatestGameResponse) -> Unit {
- return { (gameId, teamIds, gameRequest) ->
- resumedGame.set(RetrieveGameRequest(gameId, teamIds, gameRequest))
+ return { (gameId, teamIds, startScore, startIndex, numLegs, numSets) ->
+ resumedGame.set(CreateGameResponse(gameId, teamIds, startScore, startIndex, numLegs, numSets))
}
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt
index 57104c5e..7cf508ef 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Activity.kt
@@ -14,9 +14,10 @@ import nl.entreco.dartsscorecard.di.play.Play01Component
import nl.entreco.dartsscorecard.di.play.Play01Module
import nl.entreco.dartsscorecard.play.input.InputViewModel
import nl.entreco.dartsscorecard.play.score.ScoreViewModel
-import nl.entreco.domain.play.usecase.GetFinishUsecase
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.dartsscorecard.play.stats.MatchStatViewModel
+import nl.entreco.domain.play.finish.GetFinishUsecase
+import nl.entreco.domain.play.start.Play01Request
+import nl.entreco.domain.setup.game.CreateGameResponse
class Play01Activity : ViewModelActivity() {
@@ -24,6 +25,7 @@ class Play01Activity : ViewModelActivity() {
private val viewModel: Play01ViewModel by viewModelProvider { component.viewModel() }
private val scoreViewModel: ScoreViewModel by viewModelProvider { component.scoreViewModel() }
private val inputViewModel: InputViewModel by viewModelProvider { component.inputViewModel() }
+ private val statViewModel: MatchStatViewModel by viewModelProvider { component.statViewModel() }
private val finishUsecase: GetFinishUsecase by componentProvider { component.finishUsecase() }
override fun onCreate(savedInstanceState: Bundle?) {
@@ -32,6 +34,7 @@ class Play01Activity : ViewModelActivity() {
val binding = DataBindingUtil.setContentView(this, R.layout.activity_play_01)
binding.viewModel = viewModel
binding.inputViewModel = inputViewModel
+ binding.statViewModel = statViewModel
binding.scoreViewModel = scoreViewModel
binding.finishUsecase = finishUsecase
binding.animator = Play01Animator(binding)
@@ -45,7 +48,7 @@ class Play01Activity : ViewModelActivity() {
}
private fun initGame() {
- viewModel.load(retrieveSetup(intent), scoreViewModel)
+ viewModel.load(retrieveSetup(intent), scoreViewModel, statViewModel)
}
private fun toolbar(binding: ActivityPlay01Binding): Toolbar {
@@ -53,10 +56,7 @@ class Play01Activity : ViewModelActivity() {
}
private fun resumeGame() {
- viewModel.addScoreListener(scoreViewModel)
- viewModel.addPlayerListener(scoreViewModel)
- viewModel.addPlayerListener(inputViewModel)
- viewModel.addSpecialEventListener(inputViewModel)
+ viewModel.registerListeners(scoreViewModel, statViewModel, inputViewModel, scoreViewModel, inputViewModel)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -73,18 +73,24 @@ class Play01Activity : ViewModelActivity() {
companion object {
@JvmStatic
- fun retrieveSetup(intent: Intent): RetrieveGameRequest {
- return RetrieveGameRequest(intent.getLongExtra("gameId", -1),
- TeamIdsString(intent.getStringExtra("teamIds")),
- intent.getParcelableExtra("exec"))
+ fun retrieveSetup(intent: Intent): Play01Request {
+ return Play01Request(intent.getLongExtra("gameId", -1),
+ intent.getStringExtra("teamIds"),
+ intent.getIntExtra("startScore", -1),
+ intent.getIntExtra("startIndex", -1),
+ intent.getIntExtra("legs", -1),
+ intent.getIntExtra("sets", -1))
}
@JvmStatic
- fun startGame(context: Context, retrieve: RetrieveGameRequest) {
+ fun startGame(context: Context, create: CreateGameResponse) {
val intent = Intent(context, Play01Activity::class.java)
- intent.putExtra("gameId", retrieve.gameId)
- intent.putExtra("teamIds", retrieve.teamIds.toString())
- intent.putExtra("exec", retrieve.create)
+ intent.putExtra("gameId", create.gameId)
+ intent.putExtra("teamIds", create.teamIds)
+ intent.putExtra("startScore", create.startScore)
+ intent.putExtra("startIndex", create.startIndex)
+ intent.putExtra("legs", create.numLegs)
+ intent.putExtra("sets", create.numSets)
context.startActivity(intent)
}
}
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt
index d7f4b996..0fbdc7f7 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Animator.kt
@@ -1,8 +1,15 @@
package nl.entreco.dartsscorecard.play
+import android.databinding.BindingAdapter
import android.support.design.widget.BottomSheetBehavior
+import android.support.design.widget.CoordinatorLayout
+import android.view.LayoutInflater
import android.view.View
import android.view.ViewPropertyAnimator
+import android.view.ViewTreeObserver
+import kotlinx.android.synthetic.main.activity_play_01.view.*
+import kotlinx.android.synthetic.main.play_01_score.view.*
+import nl.entreco.dartsscorecard.R
import nl.entreco.dartsscorecard.databinding.ActivityPlay01Binding
import kotlin.math.max
import kotlin.math.sqrt
@@ -13,6 +20,8 @@ import kotlin.math.sqrt
class Play01Animator(binding: ActivityPlay01Binding) {
private val fab = binding.includeInput?.fab!!
+ private val scoreSheet = binding.includeScore?.scoreSheet!!
+ private val teamSheet = binding.includeScore?.teamContainer!!
private val inputSheet = binding.includeInput?.inputSheet!!
private val inputResume = binding.includeInput?.inputResume!!
private val mainSheet = binding.includeMain?.mainSheet!!
@@ -24,14 +33,23 @@ class Play01Animator(binding: ActivityPlay01Binding) {
private val stat5 = binding.includeMain?.stat5!!
private val stat6 = binding.includeMain?.stat6!!
private val stat7 = binding.includeMain?.stat7!!
+ private val name1 = binding.includeMain?.name1!!
+ private val name2 = binding.includeMain?.name2!!
+ private val score = binding.includeMain?.score!!
private val player1 = binding.includeMain?.player1!!
private val player2 = binding.includeMain?.player2!!
private val version = binding.includeMain?.version!!
init {
+
+ calculateHeightForScoreView(binding)
+
behaviour.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
+ // Slide Out ScoreViewModel
+ scoreSheet.animate().alpha(slideOffset).translationY(-scoreSheet.height * (1 - slideOffset)).setDuration(0).start()
+
// Scale Fab Out Bottom/Top
fab.animate().scaleY(slideOffset).scaleX(slideOffset).setDuration(0).start()
@@ -42,6 +60,9 @@ class Play01Animator(binding: ActivityPlay01Binding) {
// Fly In Players
player1.animate().translationX(slideOffset * -player1.width / 3).setDuration(0).start()
player2.animate().translationX(slideOffset * player2.width / 3).setDuration(0).start()
+ name1.animate().translationX(slideOffset * -name1.width).setDuration(0).start()
+ name2.animate().translationX(slideOffset * name2.width).setDuration(0).start()
+ score.animate().alpha(1 - slideOffset).scaleX(1 - slideOffset).scaleY(1 - slideOffset).setDuration(0).start()
// Fly In stats
animateState(stat1.animate(), 1, slideOffset)
@@ -79,4 +100,38 @@ class Play01Animator(binding: ActivityPlay01Binding) {
private fun animateState(anim: ViewPropertyAnimator, index: Int, slideOffset: Float) {
anim.translationY(-index * 50 * slideOffset * index).scaleX(max(0f, (1 - slideOffset * index))).alpha(1 - slideOffset).setDuration(0).start()
}
+
+ private fun calculateHeightForScoreView(binding: ActivityPlay01Binding) {
+ binding.root.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
+ override fun onPreDraw(): Boolean {
+ binding.root.viewTreeObserver.removeOnPreDrawListener(this)
+
+ val input = inputSheet.height
+ val header = binding.root.includeScore.header.height
+ val footer = binding.root.includeScore.footer.height
+ val toolbar = binding.root.includeToolbar.height
+ teamSheet.maxHeight = binding.root.height - toolbar - header - footer - input - 100
+ teamSheet.requestLayout()
+ return true
+ }
+ })
+ }
+
+ companion object {
+ @JvmStatic
+ @BindingAdapter("loading")
+ fun showLoading(view: CoordinatorLayout, loading: Boolean) {
+ if(loading) {
+ val loadingView = LayoutInflater.from(view.context).inflate(R.layout.play_01_loading, view, false)
+ view.addView(loadingView)
+ loadingView.animate().alpha(1F).start()
+ } else {
+ val count = view.childCount - 1
+ val loadingView = view.getChildAt(count)
+ loadingView.animate().alpha(0F)
+ .withEndAction { view.removeView(loadingView) }
+ .start()
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Listeners.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Listeners.kt
new file mode 100644
index 00000000..b0baf1fd
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01Listeners.kt
@@ -0,0 +1,106 @@
+package nl.entreco.dartsscorecard.play
+
+import nl.entreco.dartsscorecard.play.score.TeamScoreListener
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.model.Next
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.play.listeners.PlayerListener
+import nl.entreco.domain.play.listeners.ScoreListener
+import nl.entreco.domain.play.listeners.SpecialEventListener
+import nl.entreco.domain.play.listeners.StatListener
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 12/01/2018.
+ */
+class Play01Listeners @Inject constructor() {
+ internal val scoreListeners = mutableListOf()
+ internal val statListeners = mutableListOf()
+ internal val playerListeners = mutableListOf()
+ internal val specialEventListeners = mutableListOf>()
+
+ fun registerListeners(scoreListener: ScoreListener, statListener: StatListener, specialEventListener: SpecialEventListener<*>, vararg playerListeners: PlayerListener) {
+ addScoreListener(scoreListener)
+ addStatListener(statListener)
+ addSpecialEventListener(specialEventListener)
+ playerListeners.forEach {
+ addPlayerListener(it)
+ }
+ }
+
+ fun onLetsPlayDarts(game: Game, listeners: List) {
+ listeners.forEach { addSpecialEventListener(it) }
+ notifyNextPlayer(game.next)
+ notifyScoreChanged(game.scores, game.next.player)
+ }
+
+ fun onDartThrown(turn: Turn, by: Player) {
+ synchronized(scoreListeners) {
+ scoreListeners.forEach { it.onDartThrown(turn, by) }
+ }
+ }
+
+ fun onStatsUpdated(turnId: Long, metaId: Long) {
+ synchronized(statListeners) {
+ statListeners.forEach { it.onStatsChange(turnId, metaId) }
+ }
+ }
+
+ fun onTurnSubmitted(next: Next, turn: Turn, by: Player, scores: Array) {
+ notifyAboutSpecialEvents(next, turn, by, scores)
+ notifyScoreChanged(scores, by)
+ notifyNextPlayer(next)
+ }
+
+ private fun addScoreListener(scoreListener: ScoreListener) {
+ synchronized(scoreListeners) {
+ if (!scoreListeners.contains(scoreListener)) {
+ scoreListeners.add(scoreListener)
+ }
+ }
+ }
+
+ private fun addStatListener(statListener: StatListener) {
+ synchronized(statListeners) {
+ if (!statListeners.contains(statListener)) {
+ statListeners.add(statListener)
+ }
+ }
+ }
+
+ private fun addPlayerListener(playerListener: PlayerListener) {
+ synchronized(playerListeners) {
+ if (!playerListeners.contains(playerListener)) {
+ playerListeners.add(playerListener)
+ }
+ }
+ }
+
+ private fun addSpecialEventListener(specialEventListener: SpecialEventListener<*>) {
+ synchronized(specialEventListener) {
+ if (!specialEventListeners.contains(specialEventListener)) {
+ specialEventListeners.add(specialEventListener)
+ }
+ }
+ }
+
+ private fun notifyScoreChanged(scores: Array, by: Player) {
+ synchronized(scoreListeners) {
+ scoreListeners.forEach { it.onScoreChange(scores, by) }
+ }
+ }
+
+ private fun notifyAboutSpecialEvents(next: Next, turn: Turn, by: Player, scores: Array) {
+ synchronized(specialEventListeners) {
+ specialEventListeners.forEach { it.onSpecialEvent(next, turn, by, scores) }
+ }
+ }
+
+ private fun notifyNextPlayer(next: Next) {
+ synchronized(playerListeners) {
+ playerListeners.forEach { it.onNext(next) }
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt
index cf240283..61fe4ac8 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/Play01ViewModel.kt
@@ -1,117 +1,115 @@
package nl.entreco.dartsscorecard.play
+import android.databinding.ObservableBoolean
import nl.entreco.dartsscorecard.base.BaseViewModel
-import nl.entreco.dartsscorecard.play.score.GameLoadable
+import nl.entreco.dartsscorecard.play.score.GameLoadedNotifier
+import nl.entreco.dartsscorecard.play.score.TeamScoreListener
import nl.entreco.dartsscorecard.play.score.UiCallback
import nl.entreco.domain.Logger
-import nl.entreco.domain.model.Game
-import nl.entreco.domain.model.Next
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.*
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.play.listeners.InputListener
-import nl.entreco.domain.play.listeners.PlayerListener
-import nl.entreco.domain.play.listeners.ScoreListener
-import nl.entreco.domain.play.listeners.SpecialEventListener
-import nl.entreco.domain.play.usecase.Play01Usecase
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.StoreTurnRequest
+import nl.entreco.domain.play.listeners.*
+import nl.entreco.domain.play.start.MarkGameAsFinishedRequest
+import nl.entreco.domain.play.start.Play01Request
+import nl.entreco.domain.play.start.Play01Response
+import nl.entreco.domain.play.start.Play01Usecase
+import nl.entreco.domain.play.stats.StoreTurnRequest
+import nl.entreco.domain.play.stats.UndoTurnRequest
+import nl.entreco.domain.play.stats.UndoTurnResponse
+import nl.entreco.domain.settings.ScoreSettings
import javax.inject.Inject
/**
* Created by Entreco on 11/11/2017.
*/
-class Play01ViewModel @Inject constructor(private val playGameUsecase: Play01Usecase, private val logger: Logger) : BaseViewModel(), UiCallback, InputListener {
+class Play01ViewModel @Inject constructor(private val playGameUsecase: Play01Usecase, private val gameListeners: Play01Listeners, private val logger: Logger) : BaseViewModel(), UiCallback, InputListener {
- // Lazy to keep state
+ val loading = ObservableBoolean(true)
private lateinit var game: Game
- private val playerListeners = mutableListOf()
- private val scoreListeners = mutableListOf()
- private val specialEventListeners = mutableListOf>()
-
- fun load(request: RetrieveGameRequest, load: GameLoadable) {
- playGameUsecase.loadGameAndStart(request,
- { game, teams ->
- this.game = game
- load.startWith(teams, game.scores, request.create, this)
+ private lateinit var request: Play01Request
+ private lateinit var load: GameLoadedNotifier
+ private lateinit var loaders: Array>
+
+ fun load(request: Play01Request, load: GameLoadedNotifier, vararg loaders: GameLoadedNotifier) {
+ this.request = request
+ this.load = load
+ this.loaders = arrayOf(*loaders)
+ this.playGameUsecase.loadGameAndStart(request,
+ { response ->
+ this.game = response.game
+ load.onLoaded(response.teams, game.scores, response.settings, this)
+ loaders.forEach {
+ it.onLoaded(response.teams, game.scores, response, null)
+ }
},
{ err -> logger.e("err: $err") })
}
- override fun onLetsPlayDarts() {
- notifyNextPlayer(game.next)
- notifyScoreChanged(game.scores, game.next.player)
+ fun registerListeners(scoreListener: ScoreListener, statListener: StatListener, specialEventListener: SpecialEventListener<*>, vararg playerListeners: PlayerListener) {
+ gameListeners.registerListeners(scoreListener, statListener, specialEventListener, *playerListeners)
}
- override fun onDartThrown(turn: Turn, by: Player) {
- notifyDartThrown(turn, by)
+ override fun onLetsPlayDarts(listeners: List) {
+ this.gameListeners.onLetsPlayDarts(game, listeners)
+ this.loading.set(false)
}
- override fun onTurnSubmitted(turn: Turn, by: Player) {
- handleTurn(turn, by)
- storeTurn(turn)
+ override fun onUndo() {
+ loading.set(true)
+ playGameUsecase.undoLastTurn(UndoTurnRequest(game.id), undoSuccess(), undoFailed())
}
- private fun storeTurn(turn: Turn) {
- playGameUsecase.storeTurn(StoreTurnRequest(game.id, turn))
- }
-
- private fun handleTurn(turn: Turn, by: Player) {
- game.handle(turn)
-
- val next = game.next
- val scores = game.scores
-
- notifyAboutSpecialEvents(next, turn, by, scores)
- notifyScoreChanged(scores, by)
- notifyNextPlayer(next)
+ private fun undoFailed(): (Throwable) -> Unit {
+ return { err ->
+ logger.w("Undo failed! -> $err")
+ }
}
- fun addScoreListener(scoreListener: ScoreListener) {
- synchronized(scoreListeners) {
- if (!scoreListeners.contains(scoreListener)) {
- scoreListeners.add(scoreListener)
- }
+ private fun undoSuccess(): (UndoTurnResponse) -> Unit {
+ return {
+ logger.i("Undo done! -> go to Let's Play Darts Function")
+ load(request, load, *loaders)
}
}
- fun addPlayerListener(playerListener: PlayerListener) {
- synchronized(playerListeners) {
- if (!playerListeners.contains(playerListener)) {
- playerListeners.add(playerListener)
- }
- }
+ override fun onDartThrown(turn: Turn, by: Player) {
+ this.gameListeners.onDartThrown(turn, by)
}
- fun addSpecialEventListener(specialEventListener: SpecialEventListener<*>) {
- synchronized(specialEventListener) {
- if (!specialEventListeners.contains(specialEventListener)) {
- specialEventListeners.add(specialEventListener)
- }
- }
+ override fun onTurnSubmitted(turn: Turn, by: Player) {
+ handleTurn(turn, by)
+ storeTurn(turn, by)
}
- private fun notifyScoreChanged(scores: Array, by: Player) {
- synchronized(scoreListeners) {
- scoreListeners.forEach { it.onScoreChange(scores, by) }
- }
+ private fun handleTurn(turn: Turn, by: Player) {
+ game.handle(turn)
+
+ val next = game.next
+ val scores = game.scores
+
+ handleGameFinished(next, game.id)
+ notifyListeners(next, turn, by, scores)
}
- private fun notifyDartThrown(turn: Turn, by: Player) {
- synchronized(scoreListeners) {
- scoreListeners.forEach { it.onDartThrown(turn, by) }
- }
+ private fun storeTurn(turn: Turn, by: Player) {
+ val turnRequest = StoreTurnRequest(by.id, game.id, turn)
+ val score = game.previousScore()
+ val started = game.isNewMatchLegOrSet()
+ val turnCounter = game.getTurnCount()
+ val breakMade = game.wasBreakMade(by)
+ val turnMeta = TurnMeta(by.id, turnCounter, score, started, breakMade)
+ playGameUsecase.storeTurnAndMeta(turnRequest, turnMeta, { turnId, metaId ->
+ gameListeners.onStatsUpdated(turnId, metaId)
+ })
}
- private fun notifyAboutSpecialEvents(next: Next, turn: Turn, by: Player, scores: Array) {
- synchronized(specialEventListeners) {
- specialEventListeners.forEach { it.onSpecialEvent(next, turn, by, scores) }
+ private fun handleGameFinished(next: Next, gameId: Long) {
+ if (next.state == State.MATCH) {
+ playGameUsecase.markGameAsFinished(MarkGameAsFinishedRequest(gameId))
}
}
- private fun notifyNextPlayer(next: Next) {
- synchronized(playerListeners) {
- playerListeners.forEach { it.onNext(next) }
- }
+ private fun notifyListeners(next: Next, turn: Turn, by: Player, scores: Array) {
+ gameListeners.onTurnSubmitted(next, turn, by, scores)
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt
index bdc94c1a..cd9fbfca 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/input/InputViewModel.kt
@@ -33,6 +33,7 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva
val special = ObservableField()
val required = ObservableField()
val dartsLeft = ObservableInt()
+ val resumeDescription = ObservableInt(R.string.game_on)
private val estimator = ScoreEstimator()
private var turn = Turn()
@@ -90,6 +91,11 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva
submit(scored, listener)
}
+ fun onUndoPressed(listener: InputListener){
+ listener.onUndo()
+ clearScoreInput()
+ }
+
private fun submit(scored: Int, listener: InputListener, singles: Boolean = toggle.get()) {
if (gameIsFinished()) return
@@ -148,6 +154,7 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva
toggle.set(false)
required.set(next.requiredScore)
nextDescription.set(descriptionFromNext(next))
+ resumeDescription.set(resumeDescriptionFromNext(next))
current.set(next.player)
turn = Turn()
dartsLeft.set(turn.dartsLeft())
@@ -163,6 +170,16 @@ class InputViewModel @Inject constructor(private val analytics: Analytics, priva
}
}
+ private fun resumeDescriptionFromNext(next: Next): Int {
+ return when (next.state) {
+ State.START -> R.string.game_on
+ State.LEG -> R.string.tap_to_resume
+ State.SET -> R.string.tap_to_resume
+ State.MATCH -> R.string.game_shot_and_match
+ else -> R.string.tap_to_resume
+ }
+ }
+
private fun didFinishLeg(): Boolean {
return required.get().score == turn.total()
}
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadable.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadable.kt
deleted file mode 100644
index 77a52224..00000000
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadable.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package nl.entreco.dartsscorecard.play.score
-
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.repository.CreateGameRequest
-
-/**
- * Created by Entreco on 12/12/2017.
- */
-interface GameLoadable {
- fun startWith(teams: Array, scores: Array, create: CreateGameRequest, uiCallback: UiCallback)
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadedNotifier.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadedNotifier.kt
new file mode 100644
index 00000000..9e6931c3
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/GameLoadedNotifier.kt
@@ -0,0 +1,11 @@
+package nl.entreco.dartsscorecard.play.score
+
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.players.Team
+
+/**
+ * Created by Entreco on 12/12/2017.
+ */
+interface GameLoadedNotifier {
+ fun onLoaded(teams: Array, scores: Array, info: T, uiCallback: UiCallback?)
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt
index 4769f164..8b6b8cab 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreBindings.kt
@@ -5,7 +5,7 @@ import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import nl.entreco.domain.model.Score
import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.play.usecase.GetFinishUsecase
+import nl.entreco.domain.play.finish.GetFinishUsecase
import nl.entreco.domain.settings.ScoreSettings
@@ -23,12 +23,14 @@ abstract class ScoreBindings {
recyclerView.adapter = adapter
adapter.clear()
+ val listeners = mutableListOf()
teams.forEachIndexed { index, team ->
val vm = TeamScoreViewModel(team, scores[index], finishUsecase, starter = scoreSettings.teamStartIndex == index)
adapter.addItem(vm)
+ listeners.add(vm)
}
- uiCallback?.onLetsPlayDarts()
+ uiCallback?.onLetsPlayDarts(listeners)
}
@JvmStatic
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt
index 1b9c971c..af2f73c6 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/ScoreViewModel.kt
@@ -12,14 +12,13 @@ import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
import nl.entreco.domain.play.listeners.PlayerListener
import nl.entreco.domain.play.listeners.ScoreListener
-import nl.entreco.domain.repository.CreateGameRequest
import nl.entreco.domain.settings.ScoreSettings
import javax.inject.Inject
/**
* Created by Entreco on 18/11/2017.
*/
-class ScoreViewModel @Inject constructor(val adapter: ScoreAdapter, private val logger: Logger) : BaseViewModel(), GameLoadable, ScoreListener, PlayerListener {
+class ScoreViewModel @Inject constructor(val adapter: ScoreAdapter, private val logger: Logger) : BaseViewModel(), GameLoadedNotifier, ScoreListener, PlayerListener {
val numSets = ObservableInt(0)
val teams = ObservableArrayList()
@@ -28,17 +27,19 @@ class ScoreViewModel @Inject constructor(val adapter: ScoreAdapter, private val
val scoreSettings = ObservableField(ScoreSettings())
val uiCallback = ObservableField()
- override fun startWith(teams: Array, scores: Array, create: CreateGameRequest, uiCallback: UiCallback) {
+ override fun onLoaded(teams: Array, scores: Array, info: ScoreSettings, uiCallback: UiCallback?) {
this.uiCallback.set(uiCallback)
- this.scoreSettings.set(ScoreSettings(create.startScore, create.numLegs, create.numSets, create.startIndex))
+ this.scoreSettings.set(info)
+ this.scores.clear()
this.scores.addAll(scores)
+ this.teams.clear()
this.teams.addAll(teams)
- this.numSets.set(create.numSets)
+ this.numSets.set(info.numSets)
}
override fun onScoreChange(scores: Array, by: Player) {
logger.d("NoNICE", "1:$scores by:$by")
- scores.forEachIndexed { index, score -> adapter.teamAtIndexScored(index, score, by); }
+ scores.forEachIndexed { index, score -> adapter.teamAtIndexScored(index, score, by) }
}
override fun onDartThrown(turn: Turn, by: Player) {
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt
index 03543060..38ffb8bd 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindings.kt
@@ -6,7 +6,6 @@ import android.databinding.BindingAdapter
import android.graphics.Color
import android.support.annotation.ColorInt
import android.support.v4.graphics.ColorUtils
-import android.util.Log
import android.util.TypedValue
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AccelerateInterpolator
@@ -16,6 +15,7 @@ import android.widget.TextView
import nl.entreco.dartsscorecard.R
import nl.entreco.dartsscorecard.base.widget.CounterTextView
+
/**
* Created by Entreco on 25/11/2017.
*/
@@ -30,13 +30,29 @@ abstract class TeamScoreBindings {
view.setTarget(score.toLong())
}
+ @JvmStatic
+ @BindingAdapter("nine")
+ fun showNineDarter(view: TextView, possibleNineDart: Boolean) {
+ if (possibleNineDart) handleNine(view)
+ else clearNine(view)
+ }
+
+ private fun handleNine(view: TextView) {
+ show(view)
+ }
+
+ private fun clearNine(view: TextView) {
+ hide(view)
+ }
+
@JvmStatic
@BindingAdapter("special")
fun showSpecials(view: TextView, oldScore: Int, score: Int) {
val diff = oldScore - score
when (diff) {
180 -> handle180(view)
- 0 -> { }
+ 0 -> {
+ }
else -> {
clear(view)
}
@@ -83,8 +99,9 @@ abstract class TeamScoreBindings {
@BindingAdapter("currentScore")
fun showCurrentScore(view: CounterTextView, score: Int) {
view.setTarget(score.toLong())
+ view.measure(0, 0)
if (score <= 0) {
- view.animate().translationX(200F).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start()
+ view.animate().translationX(view.measuredWidth.toFloat() * 3).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start()
} else {
view.animate().translationX(0f).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start()
view.setTextColor(fromAttr(view.context, R.attr.scoreText))
@@ -94,8 +111,14 @@ abstract class TeamScoreBindings {
@JvmStatic
@BindingAdapter("currentTeam")
fun showCurrentTeam(view: ImageView, isCurrentTeam: Boolean) {
- val w = if (view.width.toFloat() <= 0.0f) 200f else view.width.toFloat()
- view.animate().translationX(if (isCurrentTeam) 0f else w).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start()
+ var target = 0F
+ if (!isCurrentTeam) {
+ view.measure(0, 0)
+ val w = view.width.toFloat() * 3
+ target = if (w == 0F) 50F else w
+ }
+
+ view.animate().translationX(target).setInterpolator(AccelerateDecelerateInterpolator()).setDuration(DEFAULT_ANIMATION_TIME).start()
}
@ColorInt
@@ -111,19 +134,13 @@ abstract class TeamScoreBindings {
@BindingAdapter("finish", "finishAlpha", requireAll = false)
fun showFinishWithAlpha(view: TextView, finish: String, isCurrentTeam: Boolean) {
view.text = finish
+ view.measure(0, 0)
if (finish.isEmpty()) {
- view.animate()
- .translationX(-200F)
- .setInterpolator(AccelerateDecelerateInterpolator())
- .setDuration(DEFAULT_ANIMATION_TIME).start()
+ hide(view)
} else {
- view.animate()
- .translationX(0f)
- .setInterpolator(AccelerateDecelerateInterpolator())
- .setDuration(DEFAULT_ANIMATION_TIME).start()
+ show(view)
val startColor = colorToHex(view.currentTextColor)
- Log.e("REMCO", "COLORINT:${view.currentTextColor}")
val endColor = if (isCurrentTeam) "#FFFFFFFF" else "#aaFFFFFF"
if (startColor != endColor) {
val valueAnimator = ValueAnimator.ofFloat(0.0f, 1.0f).setDuration(DEFAULT_ANIMATION_TIME)
@@ -136,6 +153,30 @@ abstract class TeamScoreBindings {
}
}
+ private fun hide(view: TextView) {
+ view.measure(0, 0)
+ val animator = ValueAnimator.ofInt(view.width, 0).setDuration(DEFAULT_ANIMATION_TIME)
+ animator.addUpdateListener {
+ val lp = view.layoutParams
+ lp.width = it.animatedValue as Int
+ view.layoutParams = lp
+ view.parent.requestLayout()
+ }
+ animator.start()
+ }
+
+ private fun show(view: TextView) {
+ view.measure(0, 0)
+ val animator = ValueAnimator.ofInt(view.width, view.measuredWidth).setDuration(DEFAULT_ANIMATION_TIME)
+ animator.addUpdateListener {
+ val lp = view.layoutParams
+ lp.width = it.animatedValue as Int
+ view.layoutParams = lp
+ view.parent.requestLayout()
+ }
+ animator.start()
+ }
+
private fun colorToHex(color: Int): String {
val alpha = Color.alpha(color)
val blue = Color.blue(color)
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreListener.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreListener.kt
new file mode 100644
index 00000000..4076163b
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreListener.kt
@@ -0,0 +1,16 @@
+package nl.entreco.dartsscorecard.play.score
+
+import nl.entreco.domain.play.listeners.SpecialEventListener
+import nl.entreco.domain.play.listeners.events.NineDartEvent
+import nl.entreco.domain.play.listeners.events.SpecialEvent
+
+
+interface TeamScoreListener : SpecialEventListener {
+ override fun handle(event: SpecialEvent) {
+ when (event) {
+ is NineDartEvent -> onNineDartEvent(event)
+ }
+ }
+
+ fun onNineDartEvent(event: NineDartEvent)
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt
index 9a328475..bcae0ed3 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModel.kt
@@ -7,33 +7,41 @@ import android.os.Handler
import nl.entreco.dartsscorecard.base.BaseViewModel
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.play.usecase.GetFinishUsecase
+import nl.entreco.domain.play.finish.GetFinishRequest
+import nl.entreco.domain.play.finish.GetFinishUsecase
+import nl.entreco.domain.play.listeners.events.NineDartEvent
import java.util.concurrent.Future
/**
* Created by Entreco on 22/11/2017.
*/
-class TeamScoreViewModel(val team: Team, startScore: Score, private val getFinishUsecase: GetFinishUsecase, private val handler: Handler = Handler(), starter: Boolean) : BaseViewModel() {
+class TeamScoreViewModel(val team: Team, startScore: Score,
+ private val getFinishUsecase: GetFinishUsecase,
+ private val handler: Handler = Handler(),
+ starter: Boolean) : BaseViewModel(), TeamScoreListener {
val finish = ObservableField("")
+ val nineDarter = ObservableBoolean(false)
val started = ObservableBoolean(starter)
val scored = ObservableInt(0)
val score = ObservableField(startScore)
val currentTeam = ObservableBoolean()
+ private var isNineDarterStillPossible = true
private var finishFuture: Future<*>? = null
fun turnUpdate(next: Next) {
+ updateNineDarter(next)
updateLegStarter(next)
updateCurrentTeam(next)
}
fun scored(input: Score, by: Player) {
- this.score.set(input.copy())
+ score.set(input.copy())
removeScoredBadgeAfter(100)
calculateFinish(input, by)
}
@@ -57,9 +65,23 @@ class TeamScoreViewModel(val team: Team, startScore: Score, private val getFinis
}
}
+ private fun updateNineDarter(next: Next) {
+ if (next.state == State.LEG || next.state == State.SET || next.state == State.START) {
+ isNineDarterStillPossible = true
+ nineDarter.set(false)
+ }
+ }
+
+ override fun onNineDartEvent(event: NineDartEvent) {
+ if (team.contains(event.by())) {
+ nineDarter.set(event.isPossible() && isNineDarterStillPossible)
+ isNineDarterStillPossible = event.isPossible()
+ }
+ }
+
private fun calculateFinish(input: Score, player: Player, turn: Turn = Turn()) {
finishFuture?.cancel(true)
- finishFuture = getFinishUsecase.calculate(input, turn, player.prefs.favoriteDouble, { finish.set(it) })
+ finishFuture = getFinishUsecase.calculate(GetFinishRequest(input, turn, player.prefs.favoriteDouble), { finish.set(it.finish) })
}
private fun removeScoredBadgeAfter(duration: Long) {
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt
index 1344faf0..a6e75207 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/score/UiCallback.kt
@@ -4,5 +4,5 @@ package nl.entreco.dartsscorecard.play.score
* Created by Entreco on 12/12/2017.
*/
interface UiCallback {
- fun onLetsPlayDarts()
+ fun onLetsPlayDarts(listeners: List)
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModel.kt
new file mode 100644
index 00000000..fbf50b0c
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModel.kt
@@ -0,0 +1,67 @@
+package nl.entreco.dartsscorecard.play.stats
+
+import android.databinding.ObservableArrayMap
+import nl.entreco.dartsscorecard.base.BaseViewModel
+import nl.entreco.dartsscorecard.play.score.GameLoadedNotifier
+import nl.entreco.dartsscorecard.play.score.UiCallback
+import nl.entreco.domain.Logger
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.listeners.StatListener
+import nl.entreco.domain.play.start.Play01Response
+import nl.entreco.domain.play.stats.*
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 11/01/2018.
+ */
+class MatchStatViewModel @Inject constructor(
+ private val fetchGameStatsUsecase: FetchGameStatsUsecase,
+ private val fetchGameStatUsecase: FetchGameStatUsecase,
+ private val logger: Logger
+) : BaseViewModel(), GameLoadedNotifier, StatListener {
+
+ val teamStats = ObservableArrayMap()
+ private lateinit var teams: Array
+
+ override fun onLoaded(teams: Array, scores: Array, info: Play01Response, uiCallback: UiCallback?) {
+ initializeStats(teams)
+ fetchGameStatsUsecase.exec(FetchGameStatsRequest(info.game.id, info.teamIds),
+ onStatsFetched(teams),
+ onStatsFailed())
+ }
+
+ private fun initializeStats(teams: Array) {
+ this.teamStats.clear()
+ this.teams = teams
+ teams.forEachIndexed { index, team ->
+ teamStats[index] = TeamStatModel(team)
+ }
+ }
+
+ private fun onStatsFetched(teams: Array): (FetchGameStatsResponse) -> Unit {
+ return { response ->
+ teams.forEachIndexed { index, team ->
+ val stats = team.players.mapNotNull {
+ response.stats[it.id]
+ }
+ teamStats[index]?.append(stats)
+ }
+ }
+ }
+
+ private fun onStatsFailed(): (Throwable) -> Unit = { err -> logger.e(err.localizedMessage) }
+
+ override fun onStatsChange(turnId: Long, metaId: Long) {
+ fetchGameStatUsecase.exec(FetchGameStatRequest(turnId, metaId), onStatUpdated(), onStatsFailed())
+ }
+
+ private fun onStatUpdated(): (FetchGameStatResponse) -> Unit {
+ return { response ->
+ val teamIndex = teams.indexOfFirst { it.contains(response.stat.playerId) }
+ if (teamIndex >= 0) {
+ teamStats[teamIndex]?.append(listOf(response.stat))
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/TeamStatModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/TeamStatModel.kt
new file mode 100644
index 00000000..63d5cf64
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/play/stats/TeamStatModel.kt
@@ -0,0 +1,98 @@
+package nl.entreco.dartsscorecard.play.stats
+
+import android.databinding.ObservableField
+import nl.entreco.domain.model.Stat
+import nl.entreco.domain.model.players.Team
+
+/**
+ * Created by entreco on 11/01/2018.
+ */
+class TeamStatModel(team: Team, private val stats: MutableList = mutableListOf()) {
+
+ companion object {
+ const val empty = "--"
+ }
+
+ val name = ObservableField(team.toString())
+ val avg = ObservableField(empty)
+ val n180 = ObservableField(empty)
+ val n140 = ObservableField(empty)
+ val n100 = ObservableField(empty)
+ val hCo = ObservableField(empty)
+ val co = ObservableField(empty)
+ val breaks = ObservableField(empty)
+
+ init {
+ if (stats.isNotEmpty()) {
+ update()
+ }
+ }
+
+ fun append(updates: List) {
+ updates.forEach { stats.add(it) }
+ if (stats.isNotEmpty()) {
+ update()
+ }
+ }
+
+ private fun update() {
+ updateAverage()
+ update180s()
+ update140s()
+ update100s()
+ updateHighestCheckout()
+ updateDoublePercentage()
+ updateBreaksMade()
+ }
+
+ private fun updateBreaksMade() {
+ val value = stats.sumBy { it.nBreaks }
+ breaks.set("$value")
+ }
+
+ private fun updateDoublePercentage() {
+ val aggregator = stats.sumBy { it.nCheckouts }
+ val denominator = stats.sumBy { it.nAtCheckout }
+
+ when (denominator) {
+ 0 -> co.set(empty)
+ else -> co.set("%.2f".format(aggregator / denominator.toDouble() * 100) + "%")
+ }
+ }
+
+ private fun updateHighestCheckout() {
+ val value = stats
+ .filter { it.highestCo.isNotEmpty() }
+ .maxBy { it.highestCo[0] }
+ ?.highestCo?.firstOrNull()
+ when (value) {
+ null -> hCo.set(empty)
+ else -> hCo.set("$value")
+ }
+ }
+
+ private fun update100s() {
+ val value = stats.sumBy { it.n100 }
+ n100.set("$value")
+ }
+
+ private fun update140s() {
+ val value = stats.sumBy { it.n140 }
+ n140.set("$value")
+ }
+
+ private fun update180s() {
+ val value = stats.sumBy { it.n180 }
+ n180.set("$value")
+ }
+
+ private fun updateAverage() {
+ val aggregator = stats.sumBy { it.totalScore }
+ val denominator = stats.sumBy { it.nDarts }
+
+ when (denominator) {
+ 0 -> avg.set(empty)
+ else -> avg.set("%.2f".format(aggregator / denominator.toDouble() * 3))
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt
index eaa8b059..e84f9d10 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Activity.kt
@@ -35,8 +35,11 @@ class Setup01Activity : ViewModelActivity() {
binding.settingsViewModel = settingsViewModel
binding.navigator = navigator
- navigator.onAddNewPlayer(0)
initToolbar(toolbar(binding), R.string.title_setup)
+
+ if (savedInstanceState == null) {
+ navigator.onAddNewPlayer(0)
+ }
}
private fun toolbar(binding: ActivitySetup01Binding): Toolbar {
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt
index 48bb7dbc..586e7f5d 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01Navigator.kt
@@ -9,14 +9,14 @@ import nl.entreco.dartsscorecard.setup.edit.EditPlayerActivity
import nl.entreco.dartsscorecard.setup.players.PlayerEditor
import nl.entreco.dartsscorecard.setup.players.PlayerViewModel
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.repository.RetrieveGameRequest
+import nl.entreco.domain.setup.game.CreateGameResponse
/**
* Created by Entreco on 02/01/2018.
*/
class Setup01Navigator(private val activity: Setup01Activity) : PlayerEditor {
- fun launch(req: RetrieveGameRequest) {
+ fun launch(req: CreateGameResponse) {
Play01Activity.startGame(activity, req)
activity.finish()
}
@@ -47,9 +47,9 @@ class Setup01Navigator(private val activity: Setup01Activity) : PlayerEditor {
if (isNewPlayer(index)) {
- if(suggestion.isEmpty()){
+ if (suggestion.isEmpty()) {
callback.onPlayerAdded(playerName)
- } else if(suggestion == "Player 1"){
+ } else if (suggestion == "Player 1") {
callback.onPlayerAdded(suggestion)
}
@@ -83,7 +83,7 @@ class Setup01Navigator(private val activity: Setup01Activity) : PlayerEditor {
fun cancelPlayerResponse(request: Intent): Intent {
val response = Intent()
response.putExtra(EXTRA_SUGGESTION, request.getStringExtra(EXTRA_SUGGESTION))
- response.putExtra(EXTRA_PLAYER_NAME, "")
+ response.putExtra(EXTRA_PLAYER_NAME, request.getStringExtra(EXTRA_SUGGESTION))
response.putExtra(EXTRA_TEAM_INDEX, request.getIntExtra(EXTRA_TEAM_INDEX, POSITION_NONE))
response.putExtra(EXTRA_POSITION_IN_LIST, request.getIntExtra(EXTRA_POSITION_IN_LIST, POSITION_NONE))
return response
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt
index 0cdb246b..852c3d77 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/Setup01ViewModel.kt
@@ -2,12 +2,12 @@ package nl.entreco.dartsscorecard.setup
import nl.entreco.dartsscorecard.base.BaseViewModel
import nl.entreco.domain.Logger
-import nl.entreco.domain.launch.TeamNamesString
-import nl.entreco.domain.launch.usecase.CreateGameUsecase
-import nl.entreco.domain.launch.usecase.ExtractTeamsUsecase
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.domain.launch.ExtractTeamsRequest
+import nl.entreco.domain.launch.ExtractTeamsResponse
+import nl.entreco.domain.launch.ExtractTeamsUsecase
+import nl.entreco.domain.setup.game.CreateGameRequest
+import nl.entreco.domain.setup.game.CreateGameResponse
+import nl.entreco.domain.setup.game.CreateGameUsecase
import javax.inject.Inject
/**
@@ -15,24 +15,24 @@ import javax.inject.Inject
*/
class Setup01ViewModel @Inject constructor(private val createGameUsecase: CreateGameUsecase, private val extractTeamsUsecase: ExtractTeamsUsecase, private val logger: Logger) : BaseViewModel() {
- fun onStartPressed(navigator: Setup01Navigator, setup: CreateGameRequest, teams: TeamNamesString) {
- ensureTeamPlayersExist(teams, {
- createNewGame(setup, it, onGameCreated(navigator), onGameCreatedFailed())
+ fun onStartPressed(navigator: Setup01Navigator, setup: CreateGameRequest, request: ExtractTeamsRequest) {
+ ensureTeamPlayersExist(request, {
+ createNewGame(setup, it.teamNames, onGameCreated(navigator), onGameCreatedFailed())
}, onGameCreatedFailed())
}
- private fun onGameCreated(navigator: Setup01Navigator): (RetrieveGameRequest) -> Unit =
+ private fun onGameCreated(navigator: Setup01Navigator): (CreateGameResponse) -> Unit =
{ req -> navigator.launch(req) }
private fun onGameCreatedFailed(): (Throwable) -> Unit = { err ->
logger.w("Unable to create game $err")
}
- private fun ensureTeamPlayersExist(teamNamesInput: TeamNamesString, done: (TeamIdsString) -> Unit, fail: (Throwable) -> Unit) {
+ private fun ensureTeamPlayersExist(teamNamesInput: ExtractTeamsRequest, done: (ExtractTeamsResponse) -> Unit, fail: (Throwable) -> Unit) {
extractTeamsUsecase.exec(teamNamesInput, done, fail)
}
- private fun createNewGame(createGameRequest: CreateGameRequest, teamNames: TeamIdsString, done: (RetrieveGameRequest) -> Unit, fail: (Throwable) -> Unit) {
+ private fun createNewGame(createGameRequest: CreateGameRequest, teamNames: String, done: (CreateGameResponse) -> Unit, fail: (Throwable) -> Unit) {
createGameUsecase.exec(createGameRequest, teamNames, done, fail)
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt
index 70c8c1ed..a1986fcb 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/ad/AdViewModel.kt
@@ -10,9 +10,9 @@ import javax.inject.Inject
*/
class AdViewModel @Inject constructor(private val analytics: Analytics) : BaseViewModel(), AdLoader.Listener {
- val loadAd = ObservableBoolean(true)
- val showAd = ObservableBoolean(false)
- val adLoader = AdLoader(this)
+ val loadAd by lazy { ObservableBoolean(true) }
+ val showAd by lazy { ObservableBoolean(false) }
+ val adLoader by lazy { AdLoader(this) }
override fun onAdClicked() {
analytics.trackAchievement("onAdClicked")
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt
index ea5f75c3..4a280984 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerActivity.kt
@@ -3,6 +3,7 @@ package nl.entreco.dartsscorecard.setup.edit
import android.databinding.DataBindingUtil
import android.os.Bundle
import android.support.v7.widget.Toolbar
+import android.view.MenuItem
import nl.entreco.dartsscorecard.R
import nl.entreco.dartsscorecard.base.ViewModelActivity
import nl.entreco.dartsscorecard.databinding.ActivityEditPlayerBinding
@@ -34,6 +35,16 @@ class EditPlayerActivity : ViewModelActivity() {
return binding.includeToolbar?.toolbar!!
}
+ override fun onOptionsItemSelected(item: MenuItem?): Boolean {
+ return when (item?.itemId) {
+ android.R.id.home -> {
+ onBackPressed()
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+ }
+
override fun onBackPressed() {
navigator.onBackPressed()
}
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt
index 1ad3b6c3..4d2852e5 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModel.kt
@@ -2,16 +2,17 @@ package nl.entreco.dartsscorecard.setup.edit
import android.databinding.ObservableArrayList
import android.databinding.ObservableField
-import android.support.design.widget.Snackbar
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.TextView
+import android.widget.Toast
import nl.entreco.dartsscorecard.R
import nl.entreco.dartsscorecard.base.BaseViewModel
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.setup.usecase.CreatePlayerRequest
-import nl.entreco.domain.setup.usecase.CreatePlayerUsecase
-import nl.entreco.domain.setup.usecase.FetchExistingPlayersUsecase
+import nl.entreco.domain.setup.players.CreatePlayerRequest
+import nl.entreco.domain.setup.players.CreatePlayerResponse
+import nl.entreco.domain.setup.players.CreatePlayerUsecase
+import nl.entreco.domain.setup.players.FetchExistingPlayersUsecase
import javax.inject.Inject
import javax.inject.Named
@@ -29,7 +30,7 @@ class EditPlayerViewModel @Inject constructor(private val createPlayerUsecase: C
init {
fetchExistingPlayersUsecase.exec(
- { players -> onPlayersRetrieved(players) },
+ { response -> onPlayersRetrieved(response.players) },
{ onPlayersFailed() }
)
}
@@ -102,10 +103,11 @@ class EditPlayerViewModel @Inject constructor(private val createPlayerUsecase: C
private fun donePressed(action: Int) = action == EditorInfo.IME_ACTION_DONE
- private fun onCreateSuccess(navigator: EditPlayerNavigator): (Player) -> Unit =
- { player -> navigator.onSelected(player) }
+ private fun onCreateSuccess(navigator: EditPlayerNavigator): (CreatePlayerResponse) -> Unit = { response ->
+ navigator.onSelected(response.player)
+ }
- private fun onCreateFailed(view : View): (Throwable) -> Unit = {
- Snackbar.make(view, R.string.err_unable_to_create_player, Snackbar.LENGTH_SHORT).show()
+ private fun onCreateFailed(view: View): (Throwable) -> Unit = {
+ Toast.makeText(view.context, R.string.err_unable_to_create_player, Toast.LENGTH_SHORT).show()
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt
index 6f71ae0a..5e25adaa 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/players/PlayersViewModel.kt
@@ -1,7 +1,7 @@
package nl.entreco.dartsscorecard.setup.players
import nl.entreco.dartsscorecard.base.BaseViewModel
-import nl.entreco.domain.launch.TeamNamesString
+import nl.entreco.domain.launch.ExtractTeamsRequest
import nl.entreco.domain.model.players.PlayerSeperator
import nl.entreco.domain.model.players.TeamSeperator
import javax.inject.Inject
@@ -11,11 +11,11 @@ import javax.inject.Inject
*/
class PlayersViewModel @Inject constructor(val adapter: PlayerAdapter) : BaseViewModel() {
- fun setupTeams(): TeamNamesString {
+ fun setupTeams(): ExtractTeamsRequest {
val teamString = StringBuilder()
val players = adapter.playersMap().groupBy { it.teamIndex.get() }.toSortedMap()
appendTeams(players, teamString)
- return TeamNamesString(teamString.toString())
+ return ExtractTeamsRequest(teamString.toString())
}
private fun appendTeams(players: Map>, teamString: StringBuilder) {
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt
index d10a090e..d7a19713 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt
+++ b/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModel.kt
@@ -5,11 +5,11 @@ import android.databinding.ObservableInt
import android.widget.AdapterView
import android.widget.SeekBar
import nl.entreco.dartsscorecard.base.BaseViewModel
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.setup.usecase.FetchPreferredSettingsUsecase
-import nl.entreco.domain.setup.usecase.FetchSettingsResponse
-import nl.entreco.domain.setup.usecase.StorePreferredSettingsUsecase
-import nl.entreco.domain.setup.usecase.StoreSettingsRequest
+import nl.entreco.domain.setup.game.CreateGameRequest
+import nl.entreco.domain.setup.settings.FetchPreferredSettingsUsecase
+import nl.entreco.domain.setup.settings.FetchSettingsResponse
+import nl.entreco.domain.setup.settings.StorePreferredSettingsUsecase
+import nl.entreco.domain.setup.settings.StoreSettingsRequest
import javax.inject.Inject
/**
diff --git a/android/DartsScorecard/app/src/main/res/drawable-nodpi/crowd.jpg b/android/DartsScorecard/app/src/main/res/drawable-nodpi/crowd.jpg
new file mode 100644
index 00000000..3a7b2a52
Binary files /dev/null and b/android/DartsScorecard/app/src/main/res/drawable-nodpi/crowd.jpg differ
diff --git a/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml b/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml
index a80a26a5..18e72a0a 100644
--- a/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml
+++ b/android/DartsScorecard/app/src/main/res/drawable/ic_player1.xml
@@ -1,75 +1,175 @@
+ android:width="100dp"
+ android:height="100dp"
+ android:viewportHeight="240.0"
+ android:viewportWidth="240.0">
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:fillColor="#FFFFFF"
+ android:fillType="nonZero"
+ android:pathData="M130.47,197.53h12.35v5.93h-12.35z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
+
+
+
+
+ android:fillType="nonZero"
+ android:pathData="M100.84,114.31C100.1,114.31 99.38,114.01 98.87,113.5C98.35,112.98 98.05,112.27 98.05,111.54C98.05,110.81 98.35,110.1 98.87,109.59C99.51,108.95 100.47,108.65 101.38,108.83C101.56,108.87 101.73,108.92 101.91,108.99C102.07,109.06 102.24,109.14 102.38,109.24C102.54,109.34 102.68,109.46 102.81,109.59C102.94,109.72 103.05,109.85 103.16,110.01C103.26,110.16 103.34,110.32 103.41,110.49C103.48,110.65 103.54,110.83 103.57,111C103.61,111.18 103.62,111.36 103.62,111.54C103.62,111.72 103.61,111.91 103.57,112.08C103.54,112.26 103.48,112.44 103.41,112.6C103.34,112.77 103.26,112.93 103.16,113.08C103.05,113.23 102.94,113.37 102.81,113.5C102.29,114.01 101.57,114.31 100.84,114.31Z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
+ android:fillType="nonZero"
+ android:pathData="M132.44,114.31C132.26,114.31 132.07,114.29 131.9,114.26C131.72,114.22 131.54,114.16 131.38,114.09C131.2,114.03 131.05,113.94 130.89,113.84C130.74,113.74 130.6,113.62 130.47,113.5C130.34,113.37 130.22,113.23 130.12,113.08C130.02,112.93 129.94,112.77 129.87,112.6C129.8,112.44 129.74,112.26 129.71,112.08C129.67,111.91 129.65,111.72 129.65,111.54C129.65,111.36 129.67,111.18 129.71,111C129.74,110.83 129.8,110.65 129.87,110.49C129.94,110.32 130.02,110.16 130.12,110.01C130.22,109.85 130.34,109.72 130.47,109.59C130.6,109.46 130.74,109.34 130.89,109.24C131.05,109.14 131.2,109.06 131.38,108.99C131.54,108.92 131.72,108.87 131.9,108.83C132.8,108.65 133.77,108.95 134.41,109.59C134.54,109.72 134.66,109.85 134.76,110.01C134.86,110.16 134.95,110.32 135.02,110.49C135.09,110.65 135.14,110.83 135.17,111C135.21,111.18 135.23,111.36 135.23,111.54C135.23,111.72 135.21,111.91 135.17,112.08C135.14,112.26 135.09,112.44 135.02,112.6C134.95,112.77 134.86,112.93 134.76,113.08C134.66,113.23 134.54,113.37 134.41,113.5C133.9,114.01 133.18,114.31 132.44,114.31Z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
+ android:fillType="nonZero"
+ android:pathData="M105.92,105.96L95.75,105.96C94.32,105.96 93.15,104.81 93.15,103.39L93.15,103.39C93.15,101.96 94.32,100.81 95.75,100.81L105.92,100.81C107.35,100.81 108.52,101.96 108.52,103.39L108.52,103.39C108.52,104.81 107.35,105.96 105.92,105.96Z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
+ android:fillType="nonZero"
+ android:pathData="M137.52,105.96L127.36,105.96C125.92,105.96 124.76,104.81 124.76,103.39L124.76,103.39C124.76,101.96 125.92,100.81 127.36,100.81L137.52,100.81C138.96,100.81 140.12,101.96 140.12,103.39L140.12,103.39C140.12,104.81 138.96,105.96 137.52,105.96Z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
+ android:fillType="nonZero"
+ android:pathData="M128,129.88C128,131.28 127.76,132.62 127.32,133.87C127.11,134.47 126.85,135.05 126.56,135.6C124.58,139.25 120.78,141.73 116.4,141.73C112.01,141.73 108.21,139.25 106.23,135.6C105.93,135.05 105.67,134.47 105.47,133.87C105.02,132.62 104.79,131.28 104.79,129.88L128,129.88Z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
-
-
-
+ android:fillType="nonZero"
+ android:pathData="M127.51,133.33C127.3,133.94 127.03,134.52 126.73,135.07C124.72,138.75 120.85,141.23 116.4,141.23C111.94,141.23 108.07,138.75 106.06,135.07C105.76,134.52 105.49,133.94 105.28,133.33L127.51,133.33Z"
+ android:strokeColor="#00000000"
+ android:strokeWidth="1" />
+
+
+
+
+
+
diff --git a/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml b/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml
index d5fc6065..f010a222 100644
--- a/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml
+++ b/android/DartsScorecard/app/src/main/res/drawable/ic_player2.xml
@@ -1,126 +1,163 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:width="100dp"
+ android:height="100dp"
+ android:viewportHeight="240.0"
+ android:viewportWidth="240.0">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/DartsScorecard/app/src/main/res/drawable/score_nine.xml b/android/DartsScorecard/app/src/main/res/drawable/score_nine.xml
new file mode 100644
index 00000000..84b849b5
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/res/drawable/score_nine.xml
@@ -0,0 +1,19 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml b/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml
index 4a52ce5b..ed36460f 100644
--- a/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/activity_edit_player.xml
@@ -57,7 +57,8 @@
+ android:layout_height="wrap_content"
+ android:fillViewport="true">
@@ -36,9 +35,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableEnd="@drawable/ic_dart"
- app:resumeGame="@{viewModel.resumedGame}"
android:onClick="@{() -> viewModel.onResumePressed(context)}"
- android:text="@string/resume" />
+ android:text="@string/resume"
+ app:resumeGame="@{viewModel.resumedGame}" />
+ android:text="@string/powered_by" />
diff --git a/android/DartsScorecard/app/src/main/res/layout/activity_play_01.xml b/android/DartsScorecard/app/src/main/res/layout/activity_play_01.xml
index 238ec416..efcc8448 100644
--- a/android/DartsScorecard/app/src/main/res/layout/activity_play_01.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/activity_play_01.xml
@@ -12,13 +12,17 @@
name="inputViewModel"
type="nl.entreco.dartsscorecard.play.input.InputViewModel" />
+
+
+ type="nl.entreco.domain.play.finish.GetFinishUsecase" />
+ android:layout_height="match_parent"
+ app:loading="@{viewModel.loading}">
+
+
-
-
-
+ android:layout_height="match_parent"
+ android:layout_marginBottom="@dimen/input_peek_height"
+ android:layout_marginEnd="@dimen/def"
+ android:layout_marginStart="@dimen/def"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior"
+ app:viewModel="@{statViewModel}" />
-
-
+
@@ -25,7 +25,7 @@
android:layout_marginStart="52dp"
android:layout_marginTop="-24dp"
android:fontFamily="sans-serif"
- android:text="Play"
+ android:text="@string/play"
android:textAllCaps="true"
android:textColor="@color/white"
android:textSize="60sp"
@@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:layout_below="@+id/play"
android:fontFamily="sans-serif-condensed"
- android:text="darts"
+ android:text="@string/darts"
android:layout_marginTop="-36dp"
android:textColor="@color/white"
android:textSize="52sp"
diff --git a/android/DartsScorecard/app/src/main/res/layout/include_resume.xml b/android/DartsScorecard/app/src/main/res/layout/include_resume.xml
index 7d327ba8..1c418c75 100644
--- a/android/DartsScorecard/app/src/main/res/layout/include_resume.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/include_resume.xml
@@ -1,8 +1,20 @@
-
+
+
+
+
+
+
+
+ android:text="@{safeUnbox(message)}" />
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/layout/play_01_input.xml b/android/DartsScorecard/app/src/main/res/layout/play_01_input.xml
index b833d584..3db18c41 100644
--- a/android/DartsScorecard/app/src/main/res/layout/play_01_input.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/play_01_input.xml
@@ -21,7 +21,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="false"
- app:behavior_peekHeight="48dp"
+ app:behavior_peekHeight="@dimen/input_peek_height"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
@@ -92,7 +92,7 @@
android:layout_toStartOf="@id/input_score"
android:text="@{viewModel.nextDescription}" />
-
-
+ layout="@layout/include_resume"
+ app:message="@{viewModel.resumeDescription}"/>
+
@@ -200,6 +201,7 @@
diff --git a/android/DartsScorecard/app/src/main/res/layout/play_01_loading.xml b/android/DartsScorecard/app/src/main/res/layout/play_01_loading.xml
new file mode 100644
index 00000000..e3164d46
--- /dev/null
+++ b/android/DartsScorecard/app/src/main/res/layout/play_01_loading.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/layout/play_01_main.xml b/android/DartsScorecard/app/src/main/res/layout/play_01_main.xml
index 2ab8e586..928f0492 100644
--- a/android/DartsScorecard/app/src/main/res/layout/play_01_main.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/play_01_main.xml
@@ -1,287 +1,301 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
-
-
+
-
+ android:alpha="0"
+ android:background="@drawable/stats_bg"
+ tools:alpha="1">
+ android:text="@string/match_stats" />
-
+
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ android:layout_below="@id/results"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
-
-
-
-
-
+ android:layout_below="@id/stat7"
+ android:gravity="center"
+ android:padding="@dimen/def"
+ android:shadowColor="#ffffff"
+ android:shadowDx="1.0"
+ android:shadowDy="1.0"
+ android:text="@string/version"
+ android:textColor="#aaffffff" />
+
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/layout/play_01_score.xml b/android/DartsScorecard/app/src/main/res/layout/play_01_score.xml
index 7e1ae876..a89b13be 100644
--- a/android/DartsScorecard/app/src/main/res/layout/play_01_score.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/play_01_score.xml
@@ -11,14 +11,15 @@
+ type="nl.entreco.domain.play.finish.GetFinishUsecase" />
-
+ android:orientation="vertical"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
-
@@ -82,15 +81,14 @@
android:layout_height="wrap_content"
android:background="@drawable/score_footer"
android:orientation="horizontal"
- android:padding="@dimen/xsmall"
- app:layout_constraintTop_toBottomOf="@id/teamContainer">
+ android:padding="@dimen/xsmall">
-
-
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/layout/select_player_view.xml b/android/DartsScorecard/app/src/main/res/layout/select_player_view.xml
index 470d9a82..8ce0b87b 100644
--- a/android/DartsScorecard/app/src/main/res/layout/select_player_view.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/select_player_view.xml
@@ -1,7 +1,6 @@
@@ -55,7 +54,7 @@
android:layout_alignParentEnd="true"
android:entries="@{entries}"
android:onItemSelected="@{(adapter,i,index,l) -> player.onTeamSelected(adapter, index)}"
- android:selectedItemPosition="@={player.teamIndex}"/>
+ android:selectedItemPosition="@={player.teamIndex}" />
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/layout/team_score_view.xml b/android/DartsScorecard/app/src/main/res/layout/team_score_view.xml
index cf5f5c68..8c61419c 100644
--- a/android/DartsScorecard/app/src/main/res/layout/team_score_view.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/team_score_view.xml
@@ -17,18 +17,44 @@
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
@@ -70,30 +96,18 @@
style="@style/Score.Hint"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:gravity="center"
app:special="@{viewModel.score.score}"
tools:text="180" />
-
-
diff --git a/android/DartsScorecard/app/src/main/res/layout/toolbar_setup_01.xml b/android/DartsScorecard/app/src/main/res/layout/toolbar_setup_01.xml
index 166d12a9..2a87d0a7 100644
--- a/android/DartsScorecard/app/src/main/res/layout/toolbar_setup_01.xml
+++ b/android/DartsScorecard/app/src/main/res/layout/toolbar_setup_01.xml
@@ -2,6 +2,8 @@
+
+
@@ -13,7 +15,8 @@
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
- app:layout_scrollFlags="scroll|enterAlways"
+ app:layout_scrollFlags="enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/values/attrs.xml b/android/DartsScorecard/app/src/main/res/values/attrs.xml
index 279f0fd0..d3bca618 100644
--- a/android/DartsScorecard/app/src/main/res/values/attrs.xml
+++ b/android/DartsScorecard/app/src/main/res/values/attrs.xml
@@ -15,6 +15,7 @@
+
@@ -25,6 +26,8 @@
+
+
diff --git a/android/DartsScorecard/app/src/main/res/values/dimens.xml b/android/DartsScorecard/app/src/main/res/values/dimens.xml
index 55b0c308..6534d099 100644
--- a/android/DartsScorecard/app/src/main/res/values/dimens.xml
+++ b/android/DartsScorecard/app/src/main/res/values/dimens.xml
@@ -6,14 +6,17 @@
16dp
32dp
+ 24dp
+ 48dp
+
80dp
300
42
42
54
- 24dp
- 48dp
60dp
+ 48dp
+ 6dp
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/main/res/values/strings.xml b/android/DartsScorecard/app/src/main/res/values/strings.xml
index 6c0a39a1..6349a055 100644
--- a/android/DartsScorecard/app/src/main/res/values/strings.xml
+++ b/android/DartsScorecard/app/src/main/res/values/strings.xml
@@ -35,6 +35,7 @@
+
Continue
Sponsored by
+ Powered by
to throw
@@ -42,6 +43,16 @@
Game on
Game shot, and the match
+
+ Match Statistics
+ Breaks Made
+ Double Success
+ Highest Out
+ 180\'s
+ 140+
+ 100+
+ average
+
BDO World Cup - semi finals
PDC World Cup - semi finals
diff --git a/android/DartsScorecard/app/src/main/res/values/strings_no_translate.xml b/android/DartsScorecard/app/src/main/res/values/strings_no_translate.xml
index ef4b6a32..01e5d4f8 100644
--- a/android/DartsScorecard/app/src/main/res/values/strings_no_translate.xml
+++ b/android/DartsScorecard/app/src/main/res/values/strings_no_translate.xml
@@ -5,8 +5,10 @@
Let\'s
Play
Darts
+ vs
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 0123456789.@
180
+ 9
- 101
- 201
diff --git a/android/DartsScorecard/app/src/main/res/values/styles_bdo.xml b/android/DartsScorecard/app/src/main/res/values/styles_bdo.xml
index 00d99fdf..926f034e 100644
--- a/android/DartsScorecard/app/src/main/res/values/styles_bdo.xml
+++ b/android/DartsScorecard/app/src/main/res/values/styles_bdo.xml
@@ -14,6 +14,7 @@
- @color/white
- @android:color/transparent
- @color/bdo_gray_light
+ - @color/black
- @color/black
- @color/white
- @color/white
@@ -31,6 +32,8 @@
- @color/bdo_yellow_dark
- @color/bdo_red_dark
- @color/bdo_red_light
+ - #FFD71B
+ - #FCC804
- @color/bdo_red_light
- @color/bdo_red_dark
- @color/bdo_yellow_light
diff --git a/android/DartsScorecard/app/src/main/res/values/styles_launch.xml b/android/DartsScorecard/app/src/main/res/values/styles_launch.xml
index 3f941779..5311d796 100644
--- a/android/DartsScorecard/app/src/main/res/values/styles_launch.xml
+++ b/android/DartsScorecard/app/src/main/res/values/styles_launch.xml
@@ -1,7 +1,7 @@
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/StylerTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/StylerTest.kt
index 2211bb6f..63c1dc17 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/StylerTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/StylerTest.kt
@@ -8,9 +8,8 @@ import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
import nl.entreco.dartsscorecard.R
+import org.junit.Assert.assertEquals
import org.junit.Test
-
-import org.junit.Assert.*
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/widget/CounterTextViewTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/widget/CounterTextViewTest.kt
index 3582ce51..4a0e99cd 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/widget/CounterTextViewTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/base/widget/CounterTextViewTest.kt
@@ -1,7 +1,7 @@
package nl.entreco.dartsscorecard.base.widget
import android.content.Context
-import org.junit.Assert.*
+import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/application/AppModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/application/AppModuleTest.kt
index 1c9e444c..76235a6c 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/application/AppModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/application/AppModuleTest.kt
@@ -4,7 +4,7 @@ import android.content.Context
import com.nhaarman.mockito_kotlin.whenever
import nl.entreco.dartsscorecard.App
import nl.entreco.dartsscorecard.DscLogger
-import nl.entreco.dartsscorecard.analytics.FirebaseAnalytics
+import nl.entreco.data.analytics.FirebaseAnalytics
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/launch/LaunchModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/launch/LaunchModuleTest.kt
index 4e4c561b..5988e807 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/launch/LaunchModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/launch/LaunchModuleTest.kt
@@ -1,6 +1,6 @@
package nl.entreco.dartsscorecard.di.launch
-import org.junit.Assert.*
+import org.junit.Assert.assertNotNull
import org.junit.Test
/**
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/setup/EditPlayerModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/setup/EditPlayerModuleTest.kt
index 461683e0..3bd2bec7 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/setup/EditPlayerModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/setup/EditPlayerModuleTest.kt
@@ -1,9 +1,8 @@
package nl.entreco.dartsscorecard.di.setup
+import org.junit.Assert.assertEquals
import org.junit.Test
-import org.junit.Assert.*
-
/**
* Created by Entreco on 02/01/2018.
*/
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModuleTest.kt
index b9aa4c13..5e76e6ec 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/GameDbModuleTest.kt
@@ -1,8 +1,8 @@
package nl.entreco.dartsscorecard.di.viewmodel.db
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.db.game.GameMapper
-import nl.entreco.data.play.repository.LocalGameRepository
+import nl.entreco.data.db.game.LocalGameRepository
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModuleTest.kt
new file mode 100644
index 00000000..3837981b
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/MetaDbModuleTest.kt
@@ -0,0 +1,36 @@
+package nl.entreco.dartsscorecard.di.viewmodel.db
+
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.meta.LocalMetaRepository
+import nl.entreco.data.db.meta.MetaMapper
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+/**
+ * Created by entreco on 24/01/2018.
+ */
+class MetaDbModuleTest{
+ @Mock private lateinit var mockDb : DscDatabase
+ @Mock private lateinit var mockMapper : MetaMapper
+ private lateinit var subject : MetaDbModule
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ subject = MetaDbModule()
+ }
+
+ @Test
+ fun provideMetaMapper() {
+ Assert.assertNotNull(subject.provideMetaMapper())
+ }
+
+ @Test
+ fun providePlayerRepository() {
+ Assert.assertNotNull(subject.provideMetaRepository(mockDb, mockMapper))
+ Assert.assertTrue(subject.provideMetaRepository(mockDb, mockMapper) is LocalMetaRepository)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModuleTest.kt
index c89b3d9f..6147e64d 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/PlayerDbModuleTest.kt
@@ -1,8 +1,8 @@
package nl.entreco.dartsscorecard.di.viewmodel.db
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.db.player.PlayerMapper
-import nl.entreco.data.play.repository.LocalPlayerRepository
+import nl.entreco.data.db.player.LocalPlayerRepository
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModuleTest.kt
index 0afb2687..83f0233e 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/db/TurnDbModuleTest.kt
@@ -1,10 +1,9 @@
package nl.entreco.dartsscorecard.di.viewmodel.db
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.db.turn.TurnMapper
+import org.junit.Assert.assertNotNull
import org.junit.Test
-
-import org.junit.Assert.*
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModuleTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModuleTest.kt
index 5ccf1880..4ac71073 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModuleTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/di/viewmodel/threading/ThreadingModuleTest.kt
@@ -1,8 +1,8 @@
package nl.entreco.dartsscorecard.di.viewmodel.threading
import android.os.Handler
-import nl.entreco.domain.executors.BgExecutor
-import nl.entreco.domain.executors.FgExecutor
+import nl.entreco.domain.common.executors.BgExecutor
+import nl.entreco.domain.common.executors.FgExecutor
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue
import org.junit.Before
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchBindingsTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchBindingsTest.kt
index f2f6508c..59662f7d 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchBindingsTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchBindingsTest.kt
@@ -4,15 +4,10 @@ import android.view.View
import android.view.ViewPropertyAnimator
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.verify
-import com.nhaarman.mockito_kotlin.verifyZeroInteractions
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
-import org.junit.Test
-
-import org.junit.Assert.*
+import nl.entreco.domain.setup.game.CreateGameResponse
import org.junit.Before
+import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
@@ -23,9 +18,9 @@ import org.mockito.junit.MockitoJUnitRunner
@RunWith(MockitoJUnitRunner::class)
class LaunchBindingsTest {
- @Mock private lateinit var mockView : View
- @Mock private lateinit var mockAnimator : ViewPropertyAnimator
- private val givenRequest = RetrieveGameRequest(33, TeamIdsString("1|2"), CreateGameRequest(1,2,3,4))
+ @Mock private lateinit var mockView: View
+ @Mock private lateinit var mockAnimator: ViewPropertyAnimator
+ private val givenRequest = CreateGameResponse(33, "1|2", 1, 2, 3, 4)
@Before
fun setUp() {
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchViewModelTest.kt
index 638acd63..c1175f24 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchViewModelTest.kt
@@ -8,11 +8,9 @@ import com.nhaarman.mockito_kotlin.whenever
import nl.entreco.dartsscorecard.play.Play01Activity
import nl.entreco.dartsscorecard.setup.Setup01Activity
import nl.entreco.domain.launch.FetchLatestGameResponse
-import nl.entreco.domain.launch.TeamNamesString
-import nl.entreco.domain.launch.usecase.RetrieveLatestGameUsecase
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.domain.launch.RetrieveLatestGameUsecase
+import nl.entreco.domain.setup.game.CreateGameRequest
+import nl.entreco.domain.setup.game.CreateGameResponse
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
@@ -27,16 +25,16 @@ class LaunchViewModelTest {
@Mock private lateinit var mockContext: Context
@Mock private lateinit var mockRetrieveGameUsecase: RetrieveLatestGameUsecase
- @Mock private lateinit var mockRetrieveGameRequest: RetrieveGameRequest
+ @Mock private lateinit var mockCreateGameResponse: CreateGameResponse
private lateinit var subject: LaunchViewModel
- private lateinit var givenTeamNames: TeamNamesString
+ private lateinit var givenTeamNames: String
private lateinit var givenRequestCreate: CreateGameRequest
private val givenGameId = 88L
- private val givenTeamIds = TeamIdsString("1|2")
- private lateinit var expectedGameRequest: RetrieveGameRequest
+ private val givenTeamIds = "1|2"
+ private lateinit var expectedGameResponse: CreateGameResponse
private lateinit var expectedFetchResponse: FetchLatestGameResponse
private val doneLatestRequestCaptor = argumentCaptor<(FetchLatestGameResponse) -> Unit>()
@@ -77,10 +75,13 @@ class LaunchViewModelTest {
}
private fun givenResumedGame() {
- whenever(mockRetrieveGameRequest.create).thenReturn(givenRequestCreate)
- whenever(mockRetrieveGameRequest.gameId).thenReturn(givenGameId)
- whenever(mockRetrieveGameRequest.teamIds).thenReturn(givenTeamIds)
- subject.resumedGame.set(mockRetrieveGameRequest)
+ whenever(mockCreateGameResponse.startIndex).thenReturn(givenRequestCreate.startIndex)
+ whenever(mockCreateGameResponse.startScore).thenReturn(givenRequestCreate.startScore)
+ whenever(mockCreateGameResponse.numSets).thenReturn(givenRequestCreate.numSets)
+ whenever(mockCreateGameResponse.numLegs).thenReturn(givenRequestCreate.numLegs)
+ whenever(mockCreateGameResponse.gameId).thenReturn(givenGameId)
+ whenever(mockCreateGameResponse.teamIds).thenReturn(givenTeamIds)
+ subject.resumedGame.set(mockCreateGameResponse)
}
@Test
@@ -91,10 +92,10 @@ class LaunchViewModelTest {
}
private fun givenTeamsAndStartScore(teams: String, start: Int) {
- givenTeamNames = TeamNamesString(teams)
+ givenTeamNames = teams
givenRequestCreate = CreateGameRequest(start, 0, 3, 3)
- expectedGameRequest = RetrieveGameRequest(givenGameId, givenTeamIds, givenRequestCreate)
- expectedFetchResponse = FetchLatestGameResponse(givenGameId, givenTeamIds, givenRequestCreate)
+ expectedGameResponse = CreateGameResponse(givenGameId, givenTeamIds, givenRequestCreate.startScore, givenRequestCreate.startIndex, givenRequestCreate.numLegs, givenRequestCreate.numSets)
+ expectedFetchResponse = FetchLatestGameResponse(givenGameId, givenTeamIds, givenRequestCreate.startScore, givenRequestCreate.startIndex, givenRequestCreate.numLegs, givenRequestCreate.numSets)
subject.retrieveLatestGame()
}
@@ -118,7 +119,7 @@ class LaunchViewModelTest {
}
private fun thenGameIsStoredInObservable() {
- assertEquals(subject.resumedGame.get(), expectedGameRequest)
+ assertEquals(subject.resumedGame.get(), expectedGameResponse)
}
private fun theObservableIsCleared() {
@@ -134,14 +135,14 @@ class LaunchViewModelTest {
private fun thenPlay01IsLaunched() {
try {
- verify(Play01Activity).startGame(mockContext, expectedGameRequest)
+ verify(Play01Activity).startGame(mockContext, expectedGameResponse)
} catch (ignore: NotAMockException) {
}
}
private fun thenPlay01IsNotLaunched() {
try {
- verify(Play01Activity).startGame(mockContext, expectedGameRequest)
+ verify(Play01Activity).startGame(mockContext, expectedGameResponse)
fail()
} catch (ignore: NotAMockException) {
}
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ActivityTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ActivityTest.kt
index 3591f047..258042c6 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ActivityTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ActivityTest.kt
@@ -6,9 +6,8 @@ import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.spy
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.domain.setup.game.CreateGameRequest
+import nl.entreco.domain.setup.game.CreateGameResponse
import org.junit.Assert.assertNotNull
import org.junit.Test
import org.junit.runner.RunWith
@@ -22,21 +21,24 @@ import org.mockito.junit.MockitoJUnitRunner
class Play01ActivityTest {
@Mock private lateinit var mockContext: Context
- @Mock private lateinit var mockRetrieveRequest: RetrieveGameRequest
+ @Mock private lateinit var mockCreateResponse: CreateGameResponse
@Mock private lateinit var mockIntent: Intent
private val givenGameId: Long = 111
private val givenTeamString = "1,2|3"
- private val givenTeamIds = TeamIdsString(givenTeamString)
+ private val givenTeamIds = givenTeamString
private val givenCreate = CreateGameRequest(1, 2, 3, 4)
val subject = spy(Play01Activity())
@Test
fun `should start Play01Activity`() {
- whenever(mockRetrieveRequest.gameId).thenReturn(givenGameId)
- whenever(mockRetrieveRequest.teamIds).thenReturn(givenTeamIds)
- whenever(mockRetrieveRequest.create).thenReturn(givenCreate)
- Play01Activity.startGame(mockContext, mockRetrieveRequest)
+ whenever(mockCreateResponse.gameId).thenReturn(givenGameId)
+ whenever(mockCreateResponse.teamIds).thenReturn(givenTeamIds)
+ whenever(mockCreateResponse.startIndex).thenReturn(givenCreate.startIndex)
+ whenever(mockCreateResponse.startScore).thenReturn(givenCreate.startScore)
+ whenever(mockCreateResponse.numLegs).thenReturn(givenCreate.numLegs)
+ whenever(mockCreateResponse.numSets).thenReturn(givenCreate.numSets)
+ Play01Activity.startGame(mockContext, mockCreateResponse)
verify(mockContext).startActivity(any())
}
@@ -44,7 +46,9 @@ class Play01ActivityTest {
fun `should retrieve setup from Intent`() {
whenever(mockIntent.getLongExtra("gameId", -1)).thenReturn(givenGameId)
whenever(mockIntent.getStringExtra("teamIds")).thenReturn(givenTeamString)
- whenever(mockIntent.getParcelableExtra("exec")).thenReturn(givenCreate)
+ whenever(mockIntent.getIntExtra("startScore", -1)).thenReturn(givenCreate.startScore)
+ whenever(mockIntent.getIntExtra("legs", -1)).thenReturn(givenCreate.numLegs)
+ whenever(mockIntent.getIntExtra("sets", -1)).thenReturn(givenCreate.numSets)
assertNotNull(Play01Activity.retrieveSetup(mockIntent))
}
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01AnimatorTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01AnimatorTest.kt
new file mode 100644
index 00000000..85c3968a
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01AnimatorTest.kt
@@ -0,0 +1,28 @@
+package nl.entreco.dartsscorecard.play
+
+import android.content.Context
+import android.support.design.widget.CoordinatorLayout
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 25/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class Play01AnimatorTest{
+
+ @Mock private lateinit var mockCoordinator : CoordinatorLayout
+ @Mock private lateinit var mockContext : Context
+
+ @Test(expected = NullPointerException::class)
+ fun `it should add loading view`() {
+ whenever(mockCoordinator.context).thenReturn(mockContext)
+ Play01Animator.showLoading(mockCoordinator, true)
+ verify(mockCoordinator).addView(any())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ListenersTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ListenersTest.kt
new file mode 100644
index 00000000..e31ba739
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ListenersTest.kt
@@ -0,0 +1,207 @@
+package nl.entreco.dartsscorecard.play
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.dartsscorecard.play.score.TeamScoreListener
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.model.Next
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.play.listeners.PlayerListener
+import nl.entreco.domain.play.listeners.ScoreListener
+import nl.entreco.domain.play.listeners.SpecialEventListener
+import nl.entreco.domain.play.listeners.StatListener
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class Play01ListenersTest {
+
+ @Mock private lateinit var mockScoreListener: ScoreListener
+ @Mock private lateinit var mockStatListener: StatListener
+ @Mock private lateinit var mockSpecialEventListener: SpecialEventListener<*>
+ @Mock private lateinit var mockPlayerListener: PlayerListener
+ private lateinit var subject : Play01Listeners
+
+ @Mock private lateinit var mockGame : Game
+ @Mock private lateinit var mockNext : Next
+ @Mock private lateinit var mockTurn : Turn
+ @Mock private lateinit var mockPlayer : Player
+ private lateinit var givenScores : Array
+ @Mock private lateinit var teamScoreListener1 : TeamScoreListener
+ @Mock private lateinit var teamScoreListener2 : TeamScoreListener
+
+ @Test
+ fun `it should register score listener`() {
+ givenSubject()
+ whenRegisteringListeners()
+ thenScoreListenerIsAdded()
+ }
+
+ @Test
+ fun `it should register special event listener`() {
+ givenSubject()
+ whenRegisteringListeners()
+ thenSpecialEventListenerIsAdded()
+ }
+
+ @Test
+ fun `it should register stat listener`() {
+ givenSubject()
+ whenRegisteringListeners()
+ thenStatListenersAreAdded()
+ }
+
+ @Test
+ fun `it should register player listener`() {
+ givenSubject()
+ whenRegisteringListeners()
+ thenPlayerListenersAreAdded()
+ }
+
+ @Test
+ fun `it should add special event listeners when "Let's Play Darts"`() {
+ givenSubject()
+ whenLetsPlayDarts()
+ thenTeamScoreListenersAreAdded()
+ }
+
+ @Test
+ fun `it should notify player listeners when "Let's Play Darts"`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenLetsPlayDarts()
+ thenPlayerListenersAreNotified()
+ }
+
+ @Test
+ fun `it should notify score listeners when "Let's Play Darts"`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenLetsPlayDarts()
+ thenScoreListenersAreNotifiedOfScoreChange()
+ }
+
+ @Test
+ fun `it should notify stat listeners when stats change`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenStatsChange()
+ thenStatListenersAreNotifiedOfDartThrown()
+ }
+
+ @Test
+ fun `it should notify score listeners when dart thrown`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenDartThrown()
+ thenScoreListenersAreNotifiedOfDartThrown()
+ }
+
+ @Test
+ fun `it should notify about special events when turn submitted`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenTurnSubmitted()
+ thenSpecialEventListenersAreNotified()
+ }
+
+ @Test
+ fun `it should notify score listeners when turn submitted`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenTurnSubmitted()
+ thenScoreListenersAreNotifiedOfScoreChange()
+ }
+
+ @Test
+ fun `it should notify player listeners when turn submitted`() {
+ givenSubject()
+ whenRegisteringListeners()
+ whenTurnSubmitted()
+ thenPlayerListenersAreNotified()
+ }
+
+ private fun givenSubject() {
+ subject = Play01Listeners()
+ }
+
+ private fun whenRegisteringListeners() {
+ subject.registerListeners(mockScoreListener, mockStatListener, mockSpecialEventListener, mockPlayerListener, mockPlayerListener)
+ }
+
+ private fun whenLetsPlayDarts() {
+ givenScores = arrayOf(Score(), Score())
+ whenever(mockNext.player).thenReturn(mockPlayer)
+ whenever(mockGame.next).thenReturn(mockNext)
+ whenever(mockGame.scores).thenReturn(givenScores)
+ subject.onLetsPlayDarts(mockGame, listOf(teamScoreListener1, teamScoreListener2))
+ }
+
+ private fun whenStatsChange() {
+ subject.onStatsUpdated(34, 44)
+ }
+
+ private fun whenDartThrown() {
+ subject.onDartThrown(mockTurn, mockPlayer)
+ }
+
+ private fun whenTurnSubmitted() {
+ givenScores = arrayOf(Score(), Score())
+ subject.onTurnSubmitted(mockNext, mockTurn, mockPlayer, givenScores)
+ }
+
+ private fun thenScoreListenerIsAdded() {
+ assertEquals(1, subject.scoreListeners.size)
+ assertEquals(mockScoreListener, subject.scoreListeners[0])
+ }
+
+ private fun thenSpecialEventListenerIsAdded() {
+ assertEquals(1, subject.specialEventListeners.size)
+ assertEquals(mockSpecialEventListener, subject.specialEventListeners[0])
+ }
+
+ private fun thenStatListenersAreAdded() {
+ assertEquals(1, subject.statListeners.size)
+ assertEquals(mockStatListener, subject.statListeners[0])
+ }
+
+ private fun thenPlayerListenersAreAdded() {
+ assertEquals(1, subject.playerListeners.size)
+ assertEquals(mockPlayerListener, subject.playerListeners[0])
+ }
+
+ private fun thenTeamScoreListenersAreAdded() {
+ assertEquals(2, subject.specialEventListeners.size)
+ assertEquals(teamScoreListener1, subject.specialEventListeners[0])
+ assertEquals(teamScoreListener2, subject.specialEventListeners[1])
+ }
+
+ private fun thenPlayerListenersAreNotified() {
+ verify(mockPlayerListener).onNext(mockNext)
+ }
+
+ private fun thenScoreListenersAreNotifiedOfScoreChange() {
+ verify(mockScoreListener).onScoreChange(any(), any())
+ }
+
+ private fun thenScoreListenersAreNotifiedOfDartThrown() {
+ verify(mockScoreListener).onDartThrown(any(), any())
+ }
+
+ private fun thenStatListenersAreNotifiedOfDartThrown() {
+ verify(mockStatListener).onStatsChange(any(), any())
+ }
+
+ private fun thenSpecialEventListenersAreNotified() {
+ verify(mockSpecialEventListener).onSpecialEvent(mockNext, mockTurn, mockPlayer, givenScores)
+ }
+}
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelTest.kt
index 0190cc25..aaf4dfe8 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelTest.kt
@@ -1,22 +1,23 @@
package nl.entreco.dartsscorecard.play
import com.nhaarman.mockito_kotlin.*
-import nl.entreco.dartsscorecard.play.score.GameLoadable
+import nl.entreco.dartsscorecard.play.score.GameLoadedNotifier
+import nl.entreco.dartsscorecard.play.score.TeamScoreListener
import nl.entreco.domain.Logger
-import nl.entreco.domain.model.Dart
-import nl.entreco.domain.model.Game
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.*
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
import nl.entreco.domain.play.Arbiter
import nl.entreco.domain.play.listeners.PlayerListener
import nl.entreco.domain.play.listeners.ScoreListener
import nl.entreco.domain.play.listeners.SpecialEventListener
-import nl.entreco.domain.play.usecase.Play01Usecase
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.domain.play.listeners.StatListener
+import nl.entreco.domain.play.start.MarkGameAsFinishedRequest
+import nl.entreco.domain.play.start.Play01Request
+import nl.entreco.domain.play.start.Play01Response
+import nl.entreco.domain.play.start.Play01Usecase
+import nl.entreco.domain.settings.ScoreSettings
+import nl.entreco.domain.setup.game.CreateGameRequest
import org.junit.Assert.assertArrayEquals
import org.junit.Before
import org.junit.Test
@@ -30,24 +31,32 @@ class Play01ViewModelTest {
private lateinit var subject: Play01ViewModel
private lateinit var game: Game
- private lateinit var req: RetrieveGameRequest
-
+ private lateinit var req: Play01Request
+ private lateinit var givenTeamScoreListeners: List
+
+ @Mock private lateinit var mockNext: Next
+ @Mock private lateinit var mockGame: Game
+ @Mock private lateinit var mockScoreSettings: ScoreSettings
+ @Mock private lateinit var mockScore: Score
+ @Mock private lateinit var mockRequest: Play01Request
@Mock private lateinit var mockPlayGameUsecase: Play01Usecase
+ @Mock private lateinit var mock01Listeners: Play01Listeners
@Mock private lateinit var mockLogger: Logger
- @Mock private lateinit var mockLoadable: GameLoadable
- @Mock private lateinit var mockScoreListener: ScoreListener
- @Mock private lateinit var mockPlayerListener: PlayerListener
- @Mock private lateinit var mockSpecialListener: SpecialEventListener<*>
+ @Mock private lateinit var mockCreatedNotifier: GameLoadedNotifier
+ @Mock private lateinit var mockGameLoadedNotifier: GameLoadedNotifier
+ @Mock private lateinit var mockTeamScoreListener: TeamScoreListener
- private val doneCaptor = argumentCaptor<(Game, Array) -> Unit>()
+ private val metaDoneCaptor = argumentCaptor<(Long, Long) -> Unit>()
+ private val doneCaptor = argumentCaptor<(Play01Response) -> Unit>()
private val failCaptor = argumentCaptor<(Throwable) -> Unit>()
private val createGameRequest: CreateGameRequest = CreateGameRequest(501, 0, 3, 2)
private val givenTeams = arrayOf(Team(arrayOf(Player("p1"))), Team(arrayOf(Player("p2"))))
private val givenScores = arrayOf(Score(), Score())
- private val mockArbiter: Arbiter = Arbiter(Score(createGameRequest.startScore))
+ private val givenArbiter: Arbiter = Arbiter(Score(createGameRequest.startScore))
private val gameId: Long = 1002
- private val teamIds = TeamIdsString("1|2")
+ private val teamIds = "1|2"
+
@Before
fun setUp() {
@@ -68,10 +77,16 @@ class Play01ViewModelTest {
thenUiIsNotReady()
}
+ @Test
+ fun `it should register listeners`() {
+ givenGameLoadedOk()
+ whenRegisteringListeners()
+ thenPlay01ListenersAreRegistered()
+ }
+
@Test
fun `it should show correct score when initial turn submitted`() {
givenGameLoadedOk()
- whenAddingPlayerListener(mockPlayerListener)
whenTurnSubmitted(Turn(Dart.SINGLE_20, Dart.SINGLE_20, Dart.SINGLE_20))
thenScoresAre(arrayOf(Score(441), Score(501)))
}
@@ -79,7 +94,6 @@ class Play01ViewModelTest {
@Test
fun `it should show correct score when second turn submitted`() {
givenGameLoadedOk()
- whenAddingPlayerListener(mockPlayerListener)
whenTurnSubmitted(Turn(Dart.SINGLE_20, Dart.SINGLE_20, Dart.SINGLE_20), Turn(Dart.TRIPLE_20, Dart.TRIPLE_20, Dart.TRIPLE_20))
thenScoresAre(arrayOf(Score(441), Score(321)))
}
@@ -87,7 +101,6 @@ class Play01ViewModelTest {
@Test
fun `it should show correct score when leg is finished`() {
givenGameLoadedOk()
- whenAddingPlayerListener(mockPlayerListener)
whenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.TEST_D250))
thenScoresAre(arrayOf(Score(501, 1, 0), Score(501, 0, 0)))
}
@@ -95,78 +108,115 @@ class Play01ViewModelTest {
@Test
fun `it should notify scoreListeners on dart thrown`() {
givenGameLoadedOk()
- whenAddingScoreListener(mockScoreListener)
whenDartThrown(Turn(Dart.SINGLE_1, Dart.SINGLE_20, Dart.DOUBLE_20))
- thenScoreListenerIsNotifiedOfDartThrown()
+ thenListenersAreNotifiedOfDartThrown()
}
-
@Test
fun `it should notify scoreListeners when turns submitted`() {
givenGameLoadedOk()
- whenAddingScoreListener(mockScoreListener)
whenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.SINGLE_20, Dart.DOUBLE_20))
- thenScoreListenerIsNotifiedOfScoreChange()
+ then01ListenersAreNotified()
}
+
@Test
fun `it should notify playerListeners when turns submitted`() {
givenGameLoadedOk()
- whenAddingPlayerListener(mockPlayerListener)
whenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.SINGLE_20, Dart.DOUBLE_20))
- thenPlayerListenerIsNotified()
+ then01ListenersAreNotified()
}
@Test
fun `it should notify specialListeners when turns submitted`() {
givenGameLoadedOk()
- whenAddingSpecialListener(mockSpecialListener)
whenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.SINGLE_20, Dart.DOUBLE_20))
- thenSpecialListenerIsNotified()
+ then01ListenersAreNotified()
}
@Test
- fun `it should notify scoreListeners when UiIsReady`() {
+ fun `it should add TeamScoreListeners when UiIsReady`() {
givenGameLoadedOk()
- whenAddingScoreListener(mockScoreListener)
whenLetsPlayDarts()
- thenScoreListenerIsNotifiedOfScoreChange()
+ thenListenersAreNotifiedOfLetsPlayDarts()
}
@Test
fun `it should notify playerListeners when UiIsReady`() {
givenGameLoadedOk()
- whenAddingPlayerListener(mockPlayerListener)
whenLetsPlayDarts()
- thenPlayerListenerIsNotified()
+ thenListenersAreNotifiedOfLetsPlayDarts()
+ }
+
+ @Test
+ fun `it should notify gameLoadedNotifiers when UiIsReady`() {
+ givenGameAndRequest(mockGameLoadedNotifier)
+ whenLoadingOk()
+ thenGameLoadedNotifiersAreNotified()
+ }
+
+ @Test
+ fun `it should mark game finished when state == MATCH`() {
+ givenFullyLoadedMockGame()
+ whenNextStateIs(State.MATCH)
+ thenGameIsMarkedAsFinished()
}
@Test
- fun `it should NOT notify specialListeners when UiIsReady`() {
+ fun `it should NOT mark game finished when state != MATCH`() {
givenGameLoadedOk()
- whenAddingSpecialListener(mockSpecialListener)
- whenLetsPlayDarts()
- thenSpecialListenerIsNotNotified()
+ whenNextStateIs(State.START)
+ thenGameIsNotMarkedAsFinished()
+ }
+
+ @Test
+ fun `it should store Turn after Turn is Handled`() {
+ givenFullyLoadedMockGame()
+ givenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.TEST_D250))
+ thenTurnIsStored()
+ }
+
+ @Test
+ fun `it should store TurnMeta after Turn is Handled`() {
+ givenFullyLoadedMockGame()
+ givenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.TEST_D250))
+ thenTurnMetaIsStored()
+ }
+
+ @Test
+ fun `it should notify statListeners when Turn & TurnMeta are stored successfully`() {
+ givenFullyLoadedMockGame()
+ givenTurnSubmitted(Turn(Dart.SINGLE_1, Dart.TEST_D250))
+ whenTurnMetaIsStoredSuccessfully()
+ thenStatListenersAreNotified()
}
- private fun givenGameAndRequest() {
- game = Game(101, mockArbiter).start(0, givenTeams)
- req = RetrieveGameRequest(gameId, teamIds, createGameRequest)
- subject = Play01ViewModel(mockPlayGameUsecase, mockLogger)
- subject.load(req, mockLoadable)
+ private fun givenGameAndRequest(vararg loaders: GameLoadedNotifier) {
+ game = Game(101, givenArbiter).start(0, givenTeams)
+ req = Play01Request(gameId, teamIds, createGameRequest.startScore, createGameRequest.startIndex, createGameRequest.numLegs, createGameRequest.numSets)
+ givenTeamScoreListeners = listOf(mockTeamScoreListener, mockTeamScoreListener)
+ subject = Play01ViewModel(mockPlayGameUsecase, mock01Listeners, mockLogger)
+ subject.load(req, mockCreatedNotifier, *loaders)
+ }
+
+ private fun givenFullyLoadedMockGame() {
+ subject = Play01ViewModel(mockPlayGameUsecase, mock01Listeners, mockLogger)
+ subject.load(mockRequest, mockCreatedNotifier)
+ verify(mockPlayGameUsecase).loadGameAndStart(any(), doneCaptor.capture(), any())
+ doneCaptor.firstValue.invoke(Play01Response(mockGame, mockScoreSettings, givenTeams, teamIds))
}
private fun whenLoadingOk() {
verify(mockPlayGameUsecase).loadGameAndStart(eq(req), doneCaptor.capture(), any())
- doneCaptor.firstValue.invoke(game, givenTeams)
+ doneCaptor.firstValue.invoke(Play01Response(game, mockScoreSettings, givenTeams, teamIds))
}
private fun thenUiIsReady() {
- verify(mockLoadable).startWith(givenTeams, givenScores, createGameRequest, subject)
+ verify(mockCreatedNotifier).onLoaded(givenTeams, givenScores, mockScoreSettings, subject)
}
private fun thenUiIsNotReady() {
- verify(mockLoadable, never()).startWith(givenTeams, givenScores, createGameRequest, subject)
+ verify(mockCreatedNotifier, never()).onLoaded(givenTeams, givenScores, mockScoreSettings, subject)
verify(mockLogger).e(any())
}
@@ -177,25 +227,7 @@ class Play01ViewModelTest {
}
private fun whenLetsPlayDarts() {
- subject.onLetsPlayDarts()
- }
-
- private fun whenAddingScoreListener(vararg listeners: ScoreListener) {
- for (listener in listeners) {
- subject.addScoreListener(listener)
- }
- }
-
- private fun whenAddingPlayerListener(vararg listeners: PlayerListener) {
- for (listener in listeners) {
- subject.addPlayerListener(listener)
- }
- }
-
- private fun whenAddingSpecialListener(vararg listeners: SpecialEventListener<*>) {
- for (listener in listeners) {
- subject.addSpecialEventListener(listener)
- }
+ subject.onLetsPlayDarts(givenTeamScoreListeners)
}
private fun whenLoadingFails(err: Throwable) {
@@ -209,33 +241,84 @@ class Play01ViewModelTest {
}
}
+ private fun givenTurnSubmitted(vararg turns: Turn) {
+ whenever(mockNext.state).thenReturn(State.START)
+ whenever(mockGame.previousScore()).thenReturn(mockScore)
+ whenever(mockGame.next).thenReturn(mockNext)
+ whenever(mockGame.id).thenReturn(gameId)
+ for (turn in turns) {
+ subject.onTurnSubmitted(turn, Player(""))
+ }
+ }
+
private fun whenDartThrown(vararg turns: Turn) {
for (turn in turns) {
subject.onDartThrown(turn, Player(""))
}
}
+ private fun whenNextStateIs(state: State) {
+ val turn = Turn()
+ whenever(mockNext.state).thenReturn(state)
+ whenever(mockGame.previousScore()).thenReturn(mockScore)
+ whenever(mockGame.next).thenReturn(mockNext)
+ whenever(mockGame.id).thenReturn(gameId)
+ subject.onTurnSubmitted(turn, Player("you won"))
+ }
+
+ private fun whenRegisteringListeners() {
+ val mockScoreListener = mock()
+ val mockStatListener = mock()
+ val mockSpecialEventListener = mock>()
+ val mockPlayerListener = mock()
+ subject.registerListeners(mockScoreListener, mockStatListener, mockSpecialEventListener, mockPlayerListener)
+ }
+
+ private fun whenTurnMetaIsStoredSuccessfully() {
+ verify(mockPlayGameUsecase).storeTurnAndMeta(any(), any(), metaDoneCaptor.capture())
+ metaDoneCaptor.lastValue.invoke(1,2)
+ }
+
private fun thenScoresAre(expected: Array) {
assertArrayEquals(expected, game.scores)
}
- private fun thenPlayerListenerIsNotified() {
- verify(mockPlayerListener).onNext(any())
+ private fun then01ListenersAreNotified() {
+ verify(mock01Listeners).onTurnSubmitted(any(), any(), any(), anyArray())
+ }
+
+ private fun thenListenersAreNotifiedOfDartThrown() {
+ verify(mock01Listeners).onDartThrown(any(), any())
}
- private fun thenScoreListenerIsNotifiedOfScoreChange() {
- verify(mockScoreListener).onScoreChange(any(), any())
+ private fun thenListenersAreNotifiedOfLetsPlayDarts() {
+ verify(mock01Listeners).onLetsPlayDarts(any(), eq(givenTeamScoreListeners))
}
- private fun thenScoreListenerIsNotifiedOfDartThrown() {
- verify(mockScoreListener).onDartThrown(any(), any())
+ private fun thenGameIsMarkedAsFinished() {
+ verify(mockPlayGameUsecase).markGameAsFinished(MarkGameAsFinishedRequest(gameId))
+ }
+
+ private fun thenGameIsNotMarkedAsFinished() {
+ verify(mockPlayGameUsecase, never()).markGameAsFinished(any())
+ }
+
+ private fun thenPlay01ListenersAreRegistered() {
+ verify(mock01Listeners).registerListeners(any(), any(), any(), any())
+ }
+
+ private fun thenGameLoadedNotifiersAreNotified() {
+ verify(mockGameLoadedNotifier).onLoaded(eq(givenTeams), eq(givenScores), any(), isNull())
+ }
+ private fun thenTurnIsStored() {
+ verify(mockPlayGameUsecase).storeTurnAndMeta(any(), any(), any())
}
- private fun thenSpecialListenerIsNotNotified() {
- verify(mockSpecialListener, never()).onSpecialEvent(any(), any(), any(), any())
+ private fun thenTurnMetaIsStored() {
+ verify(mockPlayGameUsecase).storeTurnAndMeta(any(), any(), any())
}
- private fun thenSpecialListenerIsNotified() {
- verify(mockSpecialListener).onSpecialEvent(any(), any(), any(), any())
+ private fun thenStatListenersAreNotified() {
+ verify(mock01Listeners).onStatsUpdated(1,2)
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelUndoTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelUndoTest.kt
new file mode 100644
index 00000000..9749b25e
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/Play01ViewModelUndoTest.kt
@@ -0,0 +1,104 @@
+package nl.entreco.dartsscorecard.play
+
+import com.nhaarman.mockito_kotlin.*
+import nl.entreco.dartsscorecard.play.score.GameLoadedNotifier
+import nl.entreco.domain.Logger
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.play.start.Play01Request
+import nl.entreco.domain.play.start.Play01Response
+import nl.entreco.domain.play.start.Play01Usecase
+import nl.entreco.domain.play.stats.UndoTurnRequest
+import nl.entreco.domain.play.stats.UndoTurnResponse
+import nl.entreco.domain.settings.ScoreSettings
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 25/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class Play01ViewModelUndoTest{
+
+ @Mock private lateinit var mockGame: Game
+ @Mock private lateinit var mockRequest: Play01Request
+ @Mock private lateinit var mockResponse: Play01Response
+ @Mock private lateinit var mockLoad: GameLoadedNotifier
+ @Mock private lateinit var mockLoaders: GameLoadedNotifier
+
+ @Mock private lateinit var mockPlay01Usecase: Play01Usecase
+ @Mock private lateinit var mockGameListeners: Play01Listeners
+ @Mock private lateinit var mockLogger: Logger
+ private lateinit var subject : Play01ViewModel
+
+ private val undoRequestCaptor = argumentCaptor()
+ private val load = argumentCaptor<(Play01Response)->Unit>()
+ private val done = argumentCaptor<(UndoTurnResponse)->Unit>()
+ private val fail = argumentCaptor<(Throwable)->Unit>()
+
+ @Test
+ fun `it should execute undoUsecase when undo pressed`() {
+ givenSubject()
+ whenUndoEvent()
+ thenUndoLastTurnIsCalled()
+ andLoadingIs(true)
+ }
+
+ @Test
+ fun `it should call 'load()' again when undo succeeds`() {
+ givenSubject()
+ whenUndoUsecaseSucceeds()
+ thenLoadGameAndStartIsCalledAgain()
+ }
+
+ @Test
+ fun `it should log error, when undo fails`() {
+ givenSubject()
+ whenUndoUsecaseFails(RuntimeException("db exception dude"))
+ thenErrorIsLogged()
+ }
+
+ private fun givenSubject() {
+ whenever(mockGame.id).thenReturn(5)
+ whenever(mockResponse.game).thenReturn(mockGame)
+
+ subject = Play01ViewModel(mockPlay01Usecase, mockGameListeners, mockLogger)
+ subject.load(mockRequest, mockLoad, mockLoaders)
+ verify(mockPlay01Usecase).loadGameAndStart(eq(mockRequest), load.capture(), any())
+ load.lastValue.invoke(mockResponse)
+ }
+
+ private fun whenUndoEvent() {
+ subject.onUndo()
+ }
+
+ private fun whenUndoUsecaseSucceeds() {
+ subject.onUndo()
+ verify(mockPlay01Usecase).undoLastTurn(undoRequestCaptor.capture(), done.capture(), fail.capture())
+ done.lastValue.invoke(UndoTurnResponse(1,2))
+ }
+
+ private fun whenUndoUsecaseFails(err: Throwable) {
+ subject.onUndo()
+ verify(mockPlay01Usecase).undoLastTurn(undoRequestCaptor.capture(), done.capture(), fail.capture())
+ fail.lastValue.invoke(err)
+ }
+
+ private fun thenUndoLastTurnIsCalled() {
+ verify(mockPlay01Usecase).undoLastTurn(undoRequestCaptor.capture(), done.capture(), fail.capture())
+ }
+
+ private fun thenLoadGameAndStartIsCalledAgain() {
+ verify(mockPlay01Usecase, times(2)).loadGameAndStart(any(), any(), any())
+ }
+
+ private fun thenErrorIsLogged() {
+ verify(mockLogger).w(any())
+ }
+
+ private fun andLoadingIs(expected: Boolean) {
+ assertEquals(expected, subject.loading.get())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/HintKeyProviderTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/HintKeyProviderTest.kt
index 23394145..2efcab2a 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/HintKeyProviderTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/HintKeyProviderTest.kt
@@ -1,6 +1,6 @@
package nl.entreco.dartsscorecard.play.input
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
import org.junit.Test
/**
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/InputViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/InputViewModelTest.kt
index 2ad19515..f1f9c312 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/InputViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/input/InputViewModelTest.kt
@@ -5,18 +5,14 @@ import com.nhaarman.mockito_kotlin.*
import nl.entreco.dartsscorecard.R
import nl.entreco.domain.Analytics
import nl.entreco.domain.Logger
+import nl.entreco.domain.model.*
+import nl.entreco.domain.model.players.NoPlayer
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.model.players.Team
import nl.entreco.domain.play.listeners.InputListener
import nl.entreco.domain.play.listeners.events.BustEvent
import nl.entreco.domain.play.listeners.events.NoScoreEvent
import nl.entreco.domain.play.listeners.events.SpecialEvent
-import nl.entreco.domain.model.Dart
-import nl.entreco.domain.model.Next
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
-import nl.entreco.domain.model.players.NoPlayer
-import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
-import nl.entreco.domain.model.players.Team
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Test
@@ -30,8 +26,9 @@ import org.mockito.junit.MockitoJUnitRunner
*/
@RunWith(MockitoJUnitRunner::class)
class InputViewModelTest {
- @Mock lateinit var mockAnalytics: Analytics
- @Mock lateinit var mockLogger: Logger
+
+ @Mock private lateinit var logger: Logger
+ @Mock private lateinit var analytics: Analytics
@InjectMocks private lateinit var subject: InputViewModel
@Mock private lateinit var mockListener: InputListener
@@ -61,6 +58,11 @@ class InputViewModelTest {
assertEquals(R.string.empty, subject.nextDescription.get())
}
+ @Test
+ fun `it should have 'game on' description of the resume button`() {
+ assertEquals(R.string.game_on, subject.resumeDescription.get())
+ }
+
@Test
fun `it should have empty specialEvent initially`() {
assertEquals(null, subject.special.get())
@@ -116,6 +118,12 @@ class InputViewModelTest {
thenScoredTxtIs("")
}
+ @Test
+ fun `it should call undo on Listener`() {
+ whenPressingUndo()
+ verify(mockListener).onUndo()
+ }
+
@Test
fun `it should NOT submit Turn when hint pressed, but no player is throwing`() {
whenPressingHint(0)
@@ -152,7 +160,6 @@ class InputViewModelTest {
verify(mockListener).onTurnSubmitted(any(), eq(givenPlayer))
}
-
@Test
fun `it should submit Bust when hint pressed in single Mode`() {
givenPlayer("player1")
@@ -161,6 +168,7 @@ class InputViewModelTest {
verify(mockListener).onTurnSubmitted(any(), eq(givenPlayer))
}
+
@Test
fun `it should submit Darts when 'throw' is pressed`() {
givenPlayer("player1")
@@ -297,6 +305,10 @@ class InputViewModelTest {
subject.back()
}
+ private fun whenPressingUndo() {
+ subject.onUndoPressed(mockListener)
+ }
+
private fun whenLongPressingBack() {
subject.clear()
}
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreBindingsTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreBindingsTest.kt
index 484ef3f1..a85c6e1d 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreBindingsTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreBindingsTest.kt
@@ -6,7 +6,7 @@ import com.nhaarman.mockito_kotlin.verify
import nl.entreco.domain.model.Score
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.play.usecase.GetFinishUsecase
+import nl.entreco.domain.play.finish.GetFinishUsecase
import nl.entreco.domain.settings.ScoreSettings
import org.junit.Test
import org.junit.runner.RunWith
@@ -39,7 +39,7 @@ class ScoreBindingsTest {
fun `it should notify adapter when all teams have been added`() {
ScoreBindings.addTeams(mockRecyclerView, mockScoreAdapter, givenTeams, givenScores, givenScoreSettings, mockGetFinishUsecase, mockUiCallback)
verify(mockScoreAdapter, times(givenTeams.size)).addItem(any())
- verify(mockUiCallback).onLetsPlayDarts()
+ verify(mockUiCallback).onLetsPlayDarts(any())
}
@Test
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreViewModelTest.kt
index ad00c244..6088c53e 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/ScoreViewModelTest.kt
@@ -3,14 +3,9 @@ package nl.entreco.dartsscorecard.play.score
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.verifyZeroInteractions
import nl.entreco.domain.Logger
-import nl.entreco.domain.model.Dart
-import nl.entreco.domain.model.Next
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.*
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.repository.CreateGameRequest
import nl.entreco.domain.settings.ScoreSettings
import org.junit.Assert.assertEquals
import org.junit.Before
@@ -103,7 +98,7 @@ class ScoreViewModelTest {
}
private fun `given game has started`() {
- subject.startWith(givenTeams, givenScores, CreateGameRequest(givenScoreSettings.startScore, 0, givenScoreSettings.numLegs, givenScoreSettings.numSets), mockCallback)
+ subject.onLoaded(givenTeams, givenScores, ScoreSettings(givenScoreSettings.startScore, givenScoreSettings.numLegs, givenScoreSettings.numSets, givenScoreSettings.teamStartIndex), mockCallback)
}
private fun `given NextInfo for Team`(index: Int) {
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindingsTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindingsTest.kt
index 19b38d77..137f33ee 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindingsTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreBindingsTest.kt
@@ -47,6 +47,16 @@ class TeamScoreBindingsTest {
thenStarterDrawableIsNotShown()
}
+ @Test(expected = NullPointerException::class)
+ fun `it should handle 9-darter animation`() {
+ givenNineDartEvent(true)
+ }
+
+ @Test(expected = NullPointerException::class)
+ fun `it should clear 9-darter animation`() {
+ givenNineDartEvent(false)
+ }
+
@Test
fun `it should show specials when scoring 180`() {
givenSpecialScore(180, 0)
@@ -95,7 +105,7 @@ class TeamScoreBindingsTest {
thenFinishAnimationIsShown()
}
- @Test
+ @Test(expected = NullPointerException::class)
fun `it should hide finish animation`() {
givenFinish("")
thenFinishAnimationIsNotShown()
@@ -107,6 +117,13 @@ class TeamScoreBindingsTest {
TeamScoreBindings.showSpecials(mockTextView, oldScore, score)
}
+ private fun givenNineDartEvent(nineDarts: Boolean) {
+ whenever(mockTextView.width).thenReturn(200)
+ whenever(mockTextView.measuredWidth).thenReturn(200)
+ mockAnimations()
+ TeamScoreBindings.showNineDarter(mockTextView, nineDarts)
+ }
+
private fun givenCurrentScore(score: Int) {
whenever(mockCounterTextView.animate()).thenReturn(mockAnimator)
whenever(mockCounterTextView.context).thenReturn(mockContext)
@@ -118,13 +135,13 @@ class TeamScoreBindingsTest {
private fun givenCurrentTeam(current: Boolean) {
whenever(mockImageView.animate()).thenReturn(mockAnimator)
+ whenever(mockImageView.width).thenReturn(200)
mockAnimations()
TeamScoreBindings.showCurrentTeam(mockImageView, current)
}
private fun givenFinish(finish: String) {
- whenever(mockTextView.animate()).thenReturn(mockAnimator)
- whenever(mockTextView.currentTextColor).thenReturn(-1)
+ whenever(mockTextView.width).thenReturn(200)
mockAnimations()
TeamScoreBindings.showFinishWithAlpha(mockTextView, finish, true)
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModelTest.kt
index f0dcf252..ac5e5bb2 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/score/TeamScoreViewModelTest.kt
@@ -1,18 +1,14 @@
package nl.entreco.dartsscorecard.play.score
import android.os.Handler
-import com.nhaarman.mockito_kotlin.any
-import com.nhaarman.mockito_kotlin.eq
-import com.nhaarman.mockito_kotlin.never
-import com.nhaarman.mockito_kotlin.verify
-import nl.entreco.domain.model.Dart
-import nl.entreco.domain.model.Next
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
+import com.nhaarman.mockito_kotlin.*
+import nl.entreco.domain.model.*
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.play.usecase.GetFinishUsecase
+import nl.entreco.domain.play.finish.GetFinishRequest
+import nl.entreco.domain.play.finish.GetFinishResponse
+import nl.entreco.domain.play.finish.GetFinishUsecase
+import nl.entreco.domain.play.listeners.events.NineDartEvent
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Test
@@ -37,6 +33,8 @@ class TeamScoreViewModelTest {
private lateinit var givenTurn: Turn
@Mock private lateinit var mockHandler: Handler
@Mock private lateinit var mockGetFinishUsecase: GetFinishUsecase
+ private val finishRequestCaptor = argumentCaptor()
+ private val finishResponseCaptor = argumentCaptor<(GetFinishResponse)->Unit>()
@Test
fun `when leg finished by other team, it should be false`() {
@@ -81,7 +79,7 @@ class TeamScoreViewModelTest {
fun `it should start calculating finish when player scores points`() {
givenTeamScoreViewModel(true)
whenScoringPoints(201)
- verify(mockGetFinishUsecase).calculate(eq(givenScore), any(), any(), any())
+ thenScoreIs(givenScore.score)
}
@Test
@@ -102,7 +100,7 @@ class TeamScoreViewModelTest {
fun `it should calculate finish when player in this team threw`() {
givenTeamScoreViewModel(true)
whenThrowing(Turn(), playerFromMyTeam)
- verify(mockGetFinishUsecase).calculate(any(), eq(givenTurn), any(), any())
+ thenScoreIs(501)
}
@Test
@@ -116,7 +114,44 @@ class TeamScoreViewModelTest {
fun `it should NOT calculate finish when player in other this team threw`() {
givenTeamScoreViewModel(true)
whenThrowing(Turn(Dart.DOUBLE_20), playerFromOtherTeam)
- verify(mockGetFinishUsecase, never()).calculate(any(), eq(givenTurn), any(), any())
+ verify(mockGetFinishUsecase, never()).calculate(any(), any())
+ }
+
+ @Test
+ fun `it should set nine darter when nine darter possible for team && new leg is started`() {
+ givenTeamScoreViewModel(false)
+ whenNextEventOccurs(State.LEG, playerFromMyTeam)
+ whenNineDartEvent(true, playerFromMyTeam)
+ thenNineDarterIs(true)
+ }
+
+ @Test
+ fun `it should set nine darter when nine darter possible and no non-ninedart event has occured`() {
+ givenTeamScoreViewModel(false)
+ whenNineDartEvent(true, playerFromMyTeam)
+ thenNineDarterIs(true)
+ }
+
+ @Test
+ fun `it should NOT set nine darter when nine darter possible but non-ninedart event has occured`() {
+ givenTeamScoreViewModel(false)
+ whenNineDartEvent(false, playerFromMyTeam)
+ whenNineDartEvent(true, playerFromMyTeam)
+ thenNineDarterIs(false)
+ }
+
+ @Test
+ fun `it should NOT set nine darter, when not for this team`() {
+ givenTeamScoreViewModel(false)
+ whenNineDartEvent(true, playerFromOtherTeam)
+ thenNineDarterIsNotUpdated()
+ }
+
+ @Test
+ fun `it should set nine darter not possible, when not possible for this team`() {
+ givenTeamScoreViewModel(false)
+ whenNineDartEvent(false, playerFromMyTeam)
+ thenNineDarterIs(false)
}
private fun whenLegFinishedByPlayer(player: Player) {
@@ -146,6 +181,10 @@ class TeamScoreViewModelTest {
subject.threw(turn, player)
}
+ private fun whenNineDartEvent(nineDarter: Boolean, player: Player) {
+ subject.onNineDartEvent(NineDartEvent(nineDarter, player))
+ }
+
private fun thenStartedFlagEquals(b: Boolean) {
assertEquals(b, subject.started.get())
}
@@ -153,4 +192,17 @@ class TeamScoreViewModelTest {
private fun andCurrentTeamIs(current: Boolean) {
assertEquals(current, subject.currentTeam.get())
}
-}
\ No newline at end of file
+
+ private fun thenScoreIs(score: Int) {
+ verify(mockGetFinishUsecase).calculate(finishRequestCaptor.capture(), finishResponseCaptor.capture())
+ assertEquals(score, finishRequestCaptor.lastValue.score.score)
+ }
+
+ private fun thenNineDarterIs(expected: Boolean) {
+ assertEquals(expected, subject.nineDarter.get())
+ }
+
+ private fun thenNineDarterIsNotUpdated(){
+ assertEquals(false, subject.nineDarter.get())
+ }
+}
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModelTest.kt
new file mode 100644
index 00000000..28209565
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/MatchStatViewModelTest.kt
@@ -0,0 +1,216 @@
+package nl.entreco.dartsscorecard.play.stats
+
+import com.nhaarman.mockito_kotlin.*
+import nl.entreco.domain.Logger
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.Stat
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.start.Play01Response
+import nl.entreco.domain.play.stats.*
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class MatchStatViewModelTest {
+
+ @Mock private lateinit var mockFetchGameStatsUsecase: FetchGameStatsUsecase
+ @Mock private lateinit var mockFetchGameStatUsecase: FetchGameStatUsecase
+ @Mock private lateinit var mockLogger: Logger
+ @Mock private lateinit var mockGame: Game
+ @Mock private lateinit var mockResponse: Play01Response
+ private lateinit var subject: MatchStatViewModel
+ private var givenGameId: Long = 1003
+ private var givenTeamIds: String = "1|2"
+ private var givenTeams: Array = emptyArray()
+ private var givenScores: Array = emptyArray()
+ private var givenExistingStats: Map = emptyMap()
+ private var givenUpdatedStat: Stat = Stat(1,2,3,4,5,6,7,8,9, emptyList(), emptyList())
+
+ private val statsDoneCaptor = argumentCaptor<(FetchGameStatsResponse) -> Unit>()
+ private val statDoneCaptor = argumentCaptor<(FetchGameStatResponse) -> Unit>()
+ private val failCaptor = argumentCaptor<(Throwable) -> Unit>()
+
+ @Test
+ fun `it should create teamstats when loaded empty`() {
+ givenSubjectLoaded()
+ thenNumberOfTeamStatsIs(0)
+ }
+
+ @Test
+ fun `it should create teamstats when loaded 2 teams`() {
+ givenTeams("piet", "henk")
+ givenSubjectLoaded()
+ thenNumberOfTeamStatsIs(2)
+ }
+
+ @Test
+ fun `it should fetch all stats when loaded 2 teams`() {
+ givenTeams("piet", "henk")
+ givenSubjectLoaded()
+ thenStatsAreFetched()
+ }
+
+ @Test
+ fun `it should update stats, when stats fetching successfully`() {
+ givenTeams("piet", "henk")
+ givenSubjectLoaded()
+ givenExistingStats()
+ whenStatsFetchSucceeds()
+ thenTeamStatsAreNotNull(0..1)
+ }
+
+ @Test
+ fun `it should log error, when stats fetching fails`() {
+ givenTeams("piet", "henk")
+ givenSubjectLoaded()
+ whenStatsFetchFails(RuntimeException("Oops, cannot load stats for you buddy"))
+ thenErrorIsLogged()
+ }
+
+ @Test
+ fun `it should have empty avg when loaded`() {
+ givenTeams("hein", "henk")
+ givenSubjectLoaded()
+ thenAveragesAre("--", "--")
+ }
+
+ @Test
+ fun `it should have empty 180s when loaded`() {
+ givenTeams("hein", "henk")
+ givenSubjectLoaded()
+ thenNumberOf180sIs("--", "--")
+ }
+
+ @Test
+ fun `it should update existing stats, when stats change`() {
+ givenTeams("1", "2")
+ givenSubjectLoaded()
+ whenStatsChange()
+ thenStatIsFetched()
+ }
+
+ @Test
+ fun `it should update stats, when stat fetch succeeds`() {
+ givenTeams("1", "2")
+ givenSubjectLoaded()
+ givenUpdatedStat(1,180)
+ whenStatsChangeSucceeds()
+ thenTeamStat180IsEmpty(0)
+ }
+
+ @Test
+ fun `it should log error, when stat fetch fails`() {
+ givenSubjectLoaded()
+ whenStatsChangeFails(RuntimeException("do'h"))
+ thenErrorIsLogged()
+ }
+
+ private fun givenSubjectLoaded() {
+ whenever(mockGame.id).thenReturn(givenGameId)
+ whenever(mockResponse.game).thenReturn(mockGame)
+ whenever(mockResponse.teamIds).thenReturn(givenTeamIds)
+ subject = MatchStatViewModel(mockFetchGameStatsUsecase, mockFetchGameStatUsecase, mockLogger)
+ subject.onLoaded(givenTeams, givenScores, mockResponse, null)
+ }
+
+ private fun givenTeams(vararg names: String) {
+ val teams = mutableListOf()
+ names.forEachIndexed { index, name ->
+ teams.add(Team(arrayOf(Player(name, id = index.toLong()))))
+ }
+ givenTeams = teams.toTypedArray()
+ }
+
+ private fun givenExistingStats(vararg stats: Stat) {
+ val existing = HashMap()
+ stats.forEachIndexed { index, stat ->
+ val player = givenTeams[index % givenTeams.size].players[0]
+ existing[player.id] = stat
+ }
+ givenExistingStats = existing
+ }
+
+ private fun givenUpdatedStat(playerId: Long, value: Int){
+ givenUpdatedStat = givenUpdatedStat.copy(playerId = playerId, n180 = value)
+ }
+
+ private fun whenStatsFetchSucceeds() {
+ val req = FetchGameStatsRequest(givenGameId, givenTeamIds)
+ verify(mockFetchGameStatsUsecase).exec(eq(req), statsDoneCaptor.capture(), failCaptor.capture())
+ statsDoneCaptor.lastValue.invoke(FetchGameStatsResponse(givenGameId, givenExistingStats))
+ }
+
+ private fun whenStatsFetchFails(err: Throwable) {
+ val req = FetchGameStatsRequest(givenGameId, givenTeamIds)
+ verify(mockFetchGameStatsUsecase).exec(eq(req), statsDoneCaptor.capture(), failCaptor.capture())
+ failCaptor.lastValue.invoke(err)
+ }
+
+ private fun whenStatsChange() {
+ subject.onStatsChange(1,2)
+ }
+
+ private fun whenStatsChangeSucceeds() {
+ val turnId : Long = 1
+ val metaId : Long = 20000
+ val req = FetchGameStatRequest(turnId, metaId)
+ val response = FetchGameStatResponse(givenUpdatedStat)
+ subject.onStatsChange(turnId, metaId)
+ verify(mockFetchGameStatUsecase).exec(eq(req), statDoneCaptor.capture(), failCaptor.capture())
+ statDoneCaptor.lastValue.invoke(response)
+ }
+
+ private fun whenStatsChangeFails(err: Throwable) {
+ subject.onStatsChange(8,9)
+ verify(mockFetchGameStatUsecase).exec(any(), any(), failCaptor.capture())
+ failCaptor.lastValue.invoke(err)
+ }
+
+ private fun thenStatIsFetched(){
+ verify(mockFetchGameStatUsecase).exec(any(), any(), any())
+ }
+
+ private fun thenStatsAreFetched() {
+ val req = FetchGameStatsRequest(givenGameId, givenTeamIds)
+ verify(mockFetchGameStatsUsecase).exec(eq(req), statsDoneCaptor.capture(), failCaptor.capture())
+ }
+
+ private fun thenNumberOfTeamStatsIs(expected: Int) {
+ assertEquals(expected, subject.teamStats.size)
+ }
+
+ private fun thenAveragesAre(vararg avgs: String) {
+ avgs.forEachIndexed { index, avg ->
+ assertEquals(avg, subject.teamStats[index]?.avg?.get().toString())
+ }
+ }
+
+ private fun thenNumberOf180sIs(vararg n180s: String) {
+ n180s.forEachIndexed { index, n180 ->
+ assertEquals(n180, subject.teamStats[index]?.n180?.get().toString())
+ }
+ }
+
+ private fun thenErrorIsLogged() {
+ verify(mockLogger).e(any())
+ }
+
+ private fun thenTeamStatsAreNotNull(range: IntRange) {
+ range.forEach {
+ assertNotNull(subject.teamStats[it])
+ }
+ }
+
+ private fun thenTeamStat180IsEmpty(index: Int) {
+ assertEquals("--", subject.teamStats[index]?.n180?.get())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/TeamScoreListenerTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/TeamScoreListenerTest.kt
new file mode 100644
index 00000000..f33a0bd3
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/TeamScoreListenerTest.kt
@@ -0,0 +1,48 @@
+package nl.entreco.dartsscorecard.play.stats
+
+import nl.entreco.dartsscorecard.play.score.TeamScoreListener
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.play.listeners.events.NineDartEvent
+import nl.entreco.domain.play.listeners.events.NoScoreEvent
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+import java.util.concurrent.atomic.AtomicBoolean
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class TeamScoreListenerTest {
+
+ @Mock private lateinit var mockPlayer : Player
+ private val subject = TeamScoreListenerForTesting()
+
+ @Test
+ fun `it should call NineDartEvent when nine-darter`() {
+ subject.handle(NineDartEvent(true, mockPlayer))
+ Assert.assertTrue(subject.nineDartEvent.get())
+ }
+
+ @Test
+ fun `it should call NineDartEvent when no nine-darter`() {
+ subject.handle(NineDartEvent(false, mockPlayer))
+ Assert.assertTrue(subject.nineDartEvent.get())
+ }
+
+ @Test
+ fun `it should not call NineDartEvent when different event`() {
+ subject.handle(NoScoreEvent(true))
+ Assert.assertFalse(subject.nineDartEvent.get())
+ }
+
+ private class TeamScoreListenerForTesting : TeamScoreListener {
+ val nineDartEvent = AtomicBoolean(false)
+
+ override fun onNineDartEvent(event: NineDartEvent) {
+ nineDartEvent.set(true)
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/TeamStatModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/TeamStatModelTest.kt
new file mode 100644
index 00000000..1af72324
--- /dev/null
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/play/stats/TeamStatModelTest.kt
@@ -0,0 +1,99 @@
+package nl.entreco.dartsscorecard.play.stats
+
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.model.Stat
+import nl.entreco.domain.model.players.Team
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 13/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class TeamStatModelTest {
+
+ @Mock
+ private lateinit var mockTeam: Team
+ private lateinit var subject: TeamStatModel
+
+ @Test
+ fun `it should update stats at the start`() {
+ subject = TeamStatModel(mockTeam, mutableListOf(Stat(1,2,3,4,5, 6, 15, 5, 9, listOf(10), listOf(11))))
+ thenStatsAre("2.00", "4", "5", "6", "11", "33.33%", "9")
+ }
+
+ @Test
+ fun `it should have name as specified`() {
+ givenSubject("Pjotr")
+ thenNameIs("Pjotr")
+ }
+
+ @Test
+ fun `it should have empty stats initially`() {
+ givenSubject("Pjotr")
+ thenStatsAreEmpty()
+ }
+
+ @Test
+ fun `it should update stats (normal case)`() {
+ givenSubject("Team name")
+ whenUpdating(Stat(1,2,3,4,5, 6, 15, 5, 9, listOf(10), listOf(11)))
+ thenStatsAre("2.00", "4", "5", "6", "11", "33.33%", "9")
+ }
+
+ @Test
+ fun `it should update stats (no average)`() {
+ givenSubject("Team name")
+ whenUpdating(Stat(1,0,0,4,5, 6, 15, 5, 9, listOf(10), listOf(11)))
+ thenStatsAre("--", "4", "5", "6", "11", "33.33%", "9")
+ }
+
+ @Test
+ fun `it should update stats (no percentage)`() {
+ givenSubject("Team name")
+ whenUpdating(Stat(1,2,3,4,5, 6, 0, 0, 9, listOf(10), listOf(11)))
+ thenStatsAre("2.00", "4", "5", "6", "11", "--", "9")
+ }
+
+ @Test
+ fun `it should update stats (no high checkout)`() {
+ givenSubject("Team name")
+ whenUpdating(Stat(1,2,3,4,5, 6, 0, 0, 9, emptyList(), emptyList()))
+ thenStatsAre("2.00", "4", "5", "6", "--", "--", "9")
+ }
+
+ private fun givenSubject(name: String) {
+ whenever(mockTeam.toString()).thenReturn(name)
+ subject = TeamStatModel(mockTeam)
+ }
+
+ private fun whenUpdating(stat: Stat){
+ subject.append(listOf(stat))
+ }
+
+ private fun thenStatsAreEmpty() {
+ assertEquals(TeamStatModel.empty, subject.avg.get().toString())
+ assertEquals(TeamStatModel.empty, subject.n180.get().toString())
+ assertEquals(TeamStatModel.empty, subject.n140.get().toString())
+ assertEquals(TeamStatModel.empty, subject.n100.get().toString())
+ }
+
+ private fun thenNameIs(expectedName: String) {
+ assertEquals(expectedName, subject.name.get())
+ }
+
+ private fun thenStatsAre(avg: String, n180: String, n140: String, n100: String, highestCheckout: String, checkoutPercentage: String, numberOfBreaks: String) {
+ assertEquals(avg, subject.avg.get())
+ assertEquals(n180, subject.n180.get())
+ assertEquals(n140, subject.n140.get())
+ assertEquals(n100, subject.n100.get())
+ assertEquals(highestCheckout, subject.hCo.get())
+ assertEquals(checkoutPercentage, subject.co.get())
+ assertEquals(numberOfBreaks, subject.breaks.get())
+
+
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01NavigatorTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01NavigatorTest.kt
index c714743d..9029a3a9 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01NavigatorTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01NavigatorTest.kt
@@ -10,9 +10,7 @@ import com.nhaarman.mockito_kotlin.*
import nl.entreco.dartsscorecard.setup.players.PlayerEditor
import nl.entreco.dartsscorecard.setup.players.PlayerViewModel
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.domain.setup.game.CreateGameResponse
import org.junit.Assert.assertNotNull
import org.junit.Test
import org.junit.runner.RunWith
@@ -99,7 +97,7 @@ class Setup01NavigatorTest {
@Test
fun `it should launch Play01Activity`() {
givenSubject()
- subject.launch(RetrieveGameRequest(42, TeamIdsString("1,2"), CreateGameRequest(-1, -2, -3, -4)))
+ subject.launch(CreateGameResponse(42, "1,2", -1, -2, -3, -4))
verify(mockActivity).finish()
}
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01ViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01ViewModelTest.kt
index 6b9af4a1..629170cf 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01ViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/Setup01ViewModelTest.kt
@@ -2,12 +2,12 @@ package nl.entreco.dartsscorecard.setup
import com.nhaarman.mockito_kotlin.*
import nl.entreco.domain.Logger
-import nl.entreco.domain.launch.TeamNamesString
-import nl.entreco.domain.launch.usecase.CreateGameUsecase
-import nl.entreco.domain.launch.usecase.ExtractTeamsUsecase
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
+import nl.entreco.domain.launch.ExtractTeamsRequest
+import nl.entreco.domain.launch.ExtractTeamsResponse
+import nl.entreco.domain.launch.ExtractTeamsUsecase
+import nl.entreco.domain.setup.game.CreateGameRequest
+import nl.entreco.domain.setup.game.CreateGameResponse
+import nl.entreco.domain.setup.game.CreateGameUsecase
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
@@ -24,15 +24,19 @@ class Setup01ViewModelTest {
@Mock private lateinit var mockLogger: Logger
@Mock private lateinit var mockNavigator: Setup01Navigator
- private val teamExtractDoneCaptor = argumentCaptor<(TeamIdsString) -> Unit>()
+ private val teamExtractDoneCaptor = argumentCaptor<(ExtractTeamsResponse) -> Unit>()
private val teamExtractFailCaptor = argumentCaptor<(Throwable) -> Unit>()
- private val gameCreateDoneCaptor = argumentCaptor<(RetrieveGameRequest) -> Unit>()
+ private val gameCreateDoneCaptor = argumentCaptor<(CreateGameResponse) -> Unit>()
private val gameCreateFailCaptor = argumentCaptor<(Throwable) -> Unit>()
- private lateinit var givenTeamNamesString: TeamNamesString
- private lateinit var givenTeamIdsString: TeamIdsString
- private lateinit var givenCreateRequest: CreateGameRequest
- private lateinit var givenRetrieveGameRequest: RetrieveGameRequest
+ private lateinit var givenTeamNamesString: String
+ private lateinit var givenTeamIdsString: String
+ private var givenStartScore: Int = -1
+ private var givenStartIndex: Int = -1
+ private var givenStartLegs: Int = -1
+ private var givenStartSets: Int = -1
+ private lateinit var givenCreateGameRequest: CreateGameRequest
+ private lateinit var givenCreateGameResponse: CreateGameResponse
private lateinit var subject: Setup01ViewModel
@@ -63,30 +67,34 @@ class Setup01ViewModelTest {
}
private fun givenSetupViewModel() {
- givenTeamNamesString = TeamNamesString("p1,p2|p3")
- givenTeamIdsString = TeamIdsString("1,2|3")
- givenCreateRequest = CreateGameRequest(3, 4, 5, 6)
- givenRetrieveGameRequest = RetrieveGameRequest(88, givenTeamIdsString, givenCreateRequest)
+ givenTeamNamesString = "p1,p2|p3"
+ givenTeamIdsString = "1,2|3"
+ givenStartScore = 3
+ givenStartIndex = 4
+ givenStartLegs = 5
+ givenStartSets = 6
+ givenCreateGameRequest = CreateGameRequest(givenStartScore, givenStartIndex, givenStartLegs, givenStartSets)
+ givenCreateGameResponse = CreateGameResponse(88, givenTeamIdsString, givenStartScore, givenStartIndex, givenStartLegs, givenStartSets)
subject = Setup01ViewModel(mockCreateGameUsecase, mockExtractTeamUsecase, mockLogger)
}
private fun givenStartNewGamePressed() {
- subject.onStartPressed(mockNavigator, givenCreateRequest, givenTeamNamesString)
+ subject.onStartPressed(mockNavigator, givenCreateGameRequest, ExtractTeamsRequest(givenTeamNamesString))
}
private fun whenTeamExists() {
- verify(mockExtractTeamUsecase).exec(anyBecauseRandom(), teamExtractDoneCaptor.capture(), any())
- teamExtractDoneCaptor.lastValue.invoke(givenTeamIdsString)
+ verify(mockExtractTeamUsecase).exec(eq(ExtractTeamsRequest(givenTeamNamesString)), teamExtractDoneCaptor.capture(), any())
+ teamExtractDoneCaptor.lastValue.invoke(ExtractTeamsResponse(givenTeamIdsString))
}
private fun whenTeamDoesNotExist() {
- verify(mockExtractTeamUsecase).exec(anyBecauseRandom(), any(), teamExtractFailCaptor.capture())
+ verify(mockExtractTeamUsecase).exec(eq(ExtractTeamsRequest(givenTeamNamesString)), any(), teamExtractFailCaptor.capture())
teamExtractFailCaptor.lastValue.invoke(Throwable("Unable to create team $givenTeamNamesString"))
}
private fun andGameCreateSucceeds() {
verify(mockCreateGameUsecase).exec(any(), eq(givenTeamIdsString), gameCreateDoneCaptor.capture(), any())
- gameCreateDoneCaptor.lastValue.invoke(givenRetrieveGameRequest)
+ gameCreateDoneCaptor.lastValue.invoke(givenCreateGameResponse)
}
private fun butGameCreateFails() {
@@ -95,14 +103,11 @@ class Setup01ViewModelTest {
}
private fun thenPlay01ActivityIsLaunched() {
- verify(mockNavigator).launch(givenRetrieveGameRequest)
+ verify(mockNavigator).launch(givenCreateGameResponse)
}
private fun thenPlay01ActivityIsNotLaunched() {
verifyZeroInteractions(mockNavigator)
}
-
- private fun anyBecauseRandom(): TeamNamesString = any()
-
}
\ No newline at end of file
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModelTest.kt
index e2ba9a71..4039d209 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerViewModelTest.kt
@@ -4,8 +4,9 @@ import android.view.inputmethod.EditorInfo
import android.widget.TextView
import com.nhaarman.mockito_kotlin.*
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.setup.usecase.CreatePlayerUsecase
-import nl.entreco.domain.setup.usecase.FetchExistingPlayersUsecase
+import nl.entreco.domain.setup.players.CreatePlayerUsecase
+import nl.entreco.domain.setup.players.FetchExistingPlayersResponse
+import nl.entreco.domain.setup.players.FetchExistingPlayersUsecase
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
@@ -23,7 +24,7 @@ class EditPlayerViewModelTest {
@Mock private lateinit var mockFetchUsecase: FetchExistingPlayersUsecase
@Mock private lateinit var mockView: TextView
@Mock private lateinit var mockNavigator: EditPlayerNavigator
- private val doneCaptor = argumentCaptor<(List) -> Unit>()
+ private val doneCaptor = argumentCaptor<(FetchExistingPlayersResponse) -> Unit>()
private val failCaptor = argumentCaptor<(Throwable) -> Unit>()
private lateinit var subject: EditPlayerViewModel
private lateinit var expectedPlayers: MutableList
@@ -127,7 +128,7 @@ class EditPlayerViewModelTest {
}
private fun whenFetchingSucceeds() {
- doneCaptor.lastValue.invoke(expectedPlayers)
+ doneCaptor.lastValue.invoke(FetchExistingPlayersResponse(expectedPlayers))
}
private fun whenFetchingPlayersFails(err: Throwable) {
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/players/PlayersObserverTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/players/PlayersObserverTest.kt
index c2245553..04950297 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/players/PlayersObserverTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/players/PlayersObserverTest.kt
@@ -3,8 +3,6 @@ package nl.entreco.dartsscorecard.setup.players
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.verifyZeroInteractions
import org.junit.Test
-
-import org.junit.Assert.*
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
diff --git a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModelTest.kt b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModelTest.kt
index 8ad500b3..f6375822 100644
--- a/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModelTest.kt
+++ b/android/DartsScorecard/app/src/test/java/nl/entreco/dartsscorecard/setup/settings/SettingsViewModelTest.kt
@@ -5,10 +5,10 @@ import android.widget.SeekBar
import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.setup.usecase.FetchPreferredSettingsUsecase
-import nl.entreco.domain.setup.usecase.FetchSettingsResponse
-import nl.entreco.domain.setup.usecase.StorePreferredSettingsUsecase
-import nl.entreco.domain.setup.usecase.StoreSettingsRequest
+import nl.entreco.domain.setup.settings.FetchPreferredSettingsUsecase
+import nl.entreco.domain.setup.settings.FetchSettingsResponse
+import nl.entreco.domain.setup.settings.StorePreferredSettingsUsecase
+import nl.entreco.domain.setup.settings.StoreSettingsRequest
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/android/DartsScorecard/data/build.gradle b/android/DartsScorecard/data/build.gradle
index 6b9028e2..dd0b5e38 100644
--- a/android/DartsScorecard/data/build.gradle
+++ b/android/DartsScorecard/data/build.gradle
@@ -12,10 +12,12 @@ android {
dependencies {
implementation project(":domain")
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlinVersion"
+ implementation "com.google.firebase:firebase-core:$firebase"
implementation "com.android.support:appcompat-v7:$support"
implementation "android.arch.persistence.room:runtime:$architectureComponents"
kapt "android.arch.persistence.room:compiler:$architectureComponents"
+
testImplementation "junit:junit:$junit"
testImplementation "org.mockito:mockito-core:$mockito"
testImplementation "com.nhaarman:mockito-kotlin-kt1.1:$mockitoKotlin"
diff --git a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/TestProvider.kt b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/TestProvider.kt
index 78ede201..9625be3d 100644
--- a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/TestProvider.kt
+++ b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/TestProvider.kt
@@ -23,10 +23,11 @@ class TestProvider {
table.startIndex = startIndex
table.startScore = startScore
table.teams = teamstring
+ table.finished = false
return table
}
- fun createTurn(game: Long, d1: Int, d2: Int, d3: Int, m1: Int, m2: Int, m3: Int, darts: Int): TurnTable {
+ fun createTurn(game: Long, d1: Int, d2: Int, d3: Int, m1: Int, m2: Int, m3: Int, darts: Int, player: Long): TurnTable {
val table = TurnTable()
table.d1 = d1
table.d2 = d2
@@ -36,6 +37,7 @@ class TestProvider {
table.m3 = m3
table.game = game
table.numDarts = darts
+ table.player = player
return table
}
diff --git a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/analytics/FirebaseAnalyticsTest.kt b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/analytics/FirebaseAnalyticsTest.kt
new file mode 100644
index 00000000..a7bc6fca
--- /dev/null
+++ b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/analytics/FirebaseAnalyticsTest.kt
@@ -0,0 +1,25 @@
+package nl.entreco.data.analytics
+
+import android.support.test.InstrumentationRegistry
+import android.support.test.runner.AndroidJUnit4
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+@RunWith(AndroidJUnit4::class)
+class FirebaseAnalyticsTest {
+
+ private lateinit var subject: FirebaseAnalytics
+
+ @Test
+ fun `it should track events`() {
+ givenSubject()
+ }
+
+ private fun givenSubject() {
+ val context = InstrumentationRegistry.getContext()
+ subject = FirebaseAnalytics(context)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/game/GameDaoTest.kt b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/game/GameDaoTest.kt
index d6ce4c59..9f6bdf90 100644
--- a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/game/GameDaoTest.kt
+++ b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/game/GameDaoTest.kt
@@ -2,7 +2,7 @@ package nl.entreco.data.db.game
import android.arch.persistence.room.Room
import android.support.test.InstrumentationRegistry
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.TestProvider
import org.junit.After
import org.junit.Assert
diff --git a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/player/PlayerDaoTest.kt b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/player/PlayerDaoTest.kt
index 5f8b9bbd..7037bd34 100644
--- a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/player/PlayerDaoTest.kt
+++ b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/player/PlayerDaoTest.kt
@@ -3,7 +3,7 @@ package nl.entreco.data.db.player
import android.arch.persistence.room.Room
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.TestProvider
import org.junit.After
import org.junit.Assert.assertEquals
diff --git a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/turn/TurnDaoTest.kt b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/turn/TurnDaoTest.kt
index 4226e042..ce69ea32 100644
--- a/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/turn/TurnDaoTest.kt
+++ b/android/DartsScorecard/data/src/androidTest/java/nl/entreco/data/db/turn/TurnDaoTest.kt
@@ -3,11 +3,12 @@ package nl.entreco.data.db.turn
import android.arch.persistence.room.Room
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
-import nl.entreco.data.DscDatabase
import nl.entreco.data.TestProvider
+import nl.entreco.data.db.DscDatabase
import org.junit.After
import org.junit.Assert
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -57,12 +58,12 @@ class TurnDaoTest {
}
private fun createTurn(d1: Int, d2: Int, d3: Int, m1: Int, m2: Int, m3: Int, darts: Int) {
- val turn = TestProvider.createTurn(givenGame, d1, d2, d3, m1, m2, m3, darts)
+ val turn = TestProvider.createTurn(givenGame, d1, d2, d3, m1, m2, m3, darts, 33)
turnDao.create(turn)
}
private fun givenTurn(d1: Int, d2: Int, d3: Int) {
- givenTurn = TestProvider.createTurn(1, d1, d2, d3, 1, 2, 3, 3)
+ givenTurn = TestProvider.createTurn(1, d1, d2, d3, 1, 2, 3, 3, 18)
}
private fun whenStoringTurn() {
@@ -72,6 +73,7 @@ class TurnDaoTest {
private fun verifyTurn(expected: Int, turnTable: TurnTable) {
val actual = (0 until turnTable.numDarts).sumBy { score(turnTable, it) * multiplier(turnTable, it) }
assertEquals(expected, actual)
+ assertTrue(turnTable.id >= 0)
}
private fun score(turnTable: TurnTable, dart: Int): Int {
diff --git a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/analytics/FirebaseAnalytics.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/analytics/FirebaseAnalytics.kt
similarity index 73%
rename from android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/analytics/FirebaseAnalytics.kt
rename to android/DartsScorecard/data/src/main/java/nl/entreco/data/analytics/FirebaseAnalytics.kt
index 64d413c5..66d376ae 100644
--- a/android/DartsScorecard/app/src/main/java/nl/entreco/dartsscorecard/analytics/FirebaseAnalytics.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/analytics/FirebaseAnalytics.kt
@@ -1,15 +1,16 @@
-package nl.entreco.dartsscorecard.analytics
+package nl.entreco.data.analytics
+import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
import nl.entreco.domain.Analytics
-import javax.inject.Inject
/**
* Created by Entreco on 15/11/2017.
*/
-class FirebaseAnalytics @Inject constructor(context: Context) : Analytics {
+@SuppressLint("MissingPermission")
+class FirebaseAnalytics(context: Context) : Analytics {
private val fb by lazy { FirebaseAnalytics.getInstance(context) }
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/DscDatabase.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/DscDatabase.kt
similarity index 75%
rename from android/DartsScorecard/data/src/main/java/nl/entreco/data/DscDatabase.kt
rename to android/DartsScorecard/data/src/main/java/nl/entreco/data/db/DscDatabase.kt
index 50c24269..05f4dfe4 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/DscDatabase.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/DscDatabase.kt
@@ -1,9 +1,11 @@
-package nl.entreco.data
+package nl.entreco.data.db
import android.arch.persistence.room.Database
import android.arch.persistence.room.RoomDatabase
import nl.entreco.data.db.game.GameDao
import nl.entreco.data.db.game.GameTable
+import nl.entreco.data.db.meta.MetaDao
+import nl.entreco.data.db.meta.MetaTable
import nl.entreco.data.db.player.PlayerDao
import nl.entreco.data.db.player.PlayerTable
import nl.entreco.data.db.turn.TurnDao
@@ -12,11 +14,12 @@ import nl.entreco.data.db.turn.TurnTable
/**
* Created by Entreco on 12/12/2017.
*/
-@Database(entities = [(GameTable::class), (PlayerTable::class), (TurnTable::class)], version = 1, exportSchema = false)
+@Database(entities = [(GameTable::class), (PlayerTable::class), (TurnTable::class), (MetaTable::class)], version = 1, exportSchema = false)
abstract class DscDatabase : RoomDatabase() {
abstract fun gameDao(): GameDao
abstract fun playerDao(): PlayerDao
abstract fun turnDao(): TurnDao
+ abstract fun metaDao(): MetaDao
companion object {
const val name: String = "dsc_database"
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameDao.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameDao.kt
index 4ed848a0..f46ab161 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameDao.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameDao.kt
@@ -1,9 +1,6 @@
package nl.entreco.data.db.game
-import android.arch.persistence.room.Dao
-import android.arch.persistence.room.Insert
-import android.arch.persistence.room.OnConflictStrategy
-import android.arch.persistence.room.Query
+import android.arch.persistence.room.*
/**
* Created by Entreco on 12/12/2017.
@@ -17,6 +14,12 @@ interface GameDao {
@Query("SELECT * FROM Game WHERE id = :id")
fun fetchBy(id: Long): GameTable?
+ @Update
+ fun updateGames(vararg games: GameTable)
+
+ @Update
+ fun undoFinish(vararg games: GameTable)
+
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun create(game: GameTable): Long
}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameMapper.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameMapper.kt
index 38ed0256..352629a4 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameMapper.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameMapper.kt
@@ -1,9 +1,9 @@
package nl.entreco.data.db.game
import nl.entreco.data.db.Mapper
-import nl.entreco.domain.play.Arbiter
import nl.entreco.domain.model.Game
import nl.entreco.domain.model.Score
+import nl.entreco.domain.play.Arbiter
import nl.entreco.domain.settings.ScoreSettings
/**
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameTable.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameTable.kt
index 1c47b565..0ac918a2 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameTable.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/GameTable.kt
@@ -27,4 +27,7 @@ class GameTable {
@ColumnInfo(name = "teams")
var teams: String = ""
+ @ColumnInfo(name = "finished")
+ var finished: Boolean = false
+
}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/LocalGameRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/LocalGameRepository.kt
new file mode 100644
index 00000000..ddc127e7
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/game/LocalGameRepository.kt
@@ -0,0 +1,68 @@
+package nl.entreco.data.db.game
+
+import android.support.annotation.WorkerThread
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.Mapper
+import nl.entreco.domain.launch.FetchLatestGameResponse
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.repository.GameRepository
+
+/**
+ * Created by Entreco on 15/11/2017.
+ */
+class LocalGameRepository(db: DscDatabase, private val mapper: Mapper) : GameRepository {
+
+ private val gameDao: GameDao = db.gameDao()
+
+ @Throws
+ @WorkerThread
+ override fun create(teams: String, startScore: Int, startIndex: Int, numLegs: Int, numSets: Int): Long {
+ val table = GameTable()
+
+ table.teams = teams
+ table.numLegs = numLegs
+ table.numSets = numSets
+ table.startIndex = startIndex
+ table.startScore = startScore
+
+ return gameDao.create(table)
+ }
+
+ @WorkerThread
+ override fun finish(id: Long) {
+ val gameTable = gameDao.fetchBy(id)!!
+ gameTable.finished = true
+ gameDao.updateGames(gameTable)
+ }
+
+ @WorkerThread
+ override fun undoFinish(id: Long) {
+ val gameTable = gameDao.fetchBy(id)!!
+ gameTable.finished = false
+ gameDao.undoFinish(gameTable)
+ }
+
+ @Throws
+ @WorkerThread
+ override fun fetchBy(id: Long): Game {
+ val gameTable = gameDao.fetchBy(id)
+ ?: throw IllegalStateException("Game $id does not exist")
+ return mapper.to(gameTable)
+ }
+
+ @Throws
+ @WorkerThread
+ override fun fetchLatest(): FetchLatestGameResponse {
+ val allUnfinishedGames = gameDao.fetchAll().filter { !it.finished }
+ return if (allUnfinishedGames.isEmpty()) throw IllegalStateException("no Games found")
+ else {
+ val latestGame = allUnfinishedGames.first()
+ FetchLatestGameResponse(latestGame.id,
+ latestGame.teams,
+ latestGame.startScore,
+ latestGame.startIndex,
+ latestGame.numLegs,
+ latestGame.numSets)
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/LocalMetaRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/LocalMetaRepository.kt
new file mode 100644
index 00000000..3c3b286a
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/LocalMetaRepository.kt
@@ -0,0 +1,24 @@
+package nl.entreco.data.db.meta
+
+import android.support.annotation.WorkerThread
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.domain.model.TurnMeta
+import nl.entreco.domain.repository.MetaRepository
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+class LocalMetaRepository(db: DscDatabase, private val mapper: MetaMapper) : MetaRepository {
+ private val metaDao: MetaDao = db.metaDao()
+
+ @WorkerThread
+ override fun create(turnId: Long, gameId: Long, meta: TurnMeta, atDouble: Int): Long {
+ val table = mapper.from(gameId, turnId, meta, atDouble)
+ return metaDao.create(table)
+ }
+
+ @WorkerThread
+ override fun undo(gameId: Long): Int {
+ return metaDao.undoLast(gameId)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaDao.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaDao.kt
new file mode 100644
index 00000000..ea621019
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaDao.kt
@@ -0,0 +1,28 @@
+package nl.entreco.data.db.meta
+
+import android.arch.persistence.room.Dao
+import android.arch.persistence.room.Insert
+import android.arch.persistence.room.OnConflictStrategy
+import android.arch.persistence.room.Query
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+@Dao
+interface MetaDao {
+
+ @Query("SELECT * FROM TurnMeta WHERE id = :id")
+ fun fetchById(id: Long): MetaTable
+
+ @Query("SELECT * FROM TurnMeta WHERE player = :playerId")
+ fun fetchByPlayer(playerId: Long): List
+
+ @Query("SELECT * FROM TurnMeta WHERE game = :gameId")
+ fun fetchAll(gameId: Long): List
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun create(stat: MetaTable): Long
+
+ @Query("DELETE FROM TurnMeta WHERE game = :gameId AND id = (SELECT MAX(id) FROM TurnMeta)")
+ fun undoLast(gameId: Long): Int
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaMapper.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaMapper.kt
new file mode 100644
index 00000000..60875cda
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaMapper.kt
@@ -0,0 +1,29 @@
+package nl.entreco.data.db.meta
+
+import nl.entreco.data.db.Mapper
+import nl.entreco.domain.model.TurnMeta
+
+/**
+ * Created by entreco on 20/01/2018.
+ */
+class MetaMapper : Mapper {
+
+ override fun to(from: TurnMeta): MetaTable {
+ TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
+ }
+
+ fun from(gameId: Long, turnId: Long, turnMeta: TurnMeta, atDouble: Int): MetaTable {
+ val table = MetaTable()
+ table.turnId = turnId
+ table.gameId = gameId
+ table.playerId = turnMeta.playerId
+ table.legNumber = turnMeta.score.leg
+ table.setNumber = turnMeta.score.set
+ table.turnInLeg = turnMeta.turnNumber
+ table.score = turnMeta.score.score
+ table.atCheckout = atDouble
+ table.started = turnMeta.started
+ table.breakMade = turnMeta.breakMade
+ return table
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaTable.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaTable.kt
new file mode 100644
index 00000000..89186490
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/meta/MetaTable.kt
@@ -0,0 +1,44 @@
+package nl.entreco.data.db.meta
+
+import android.arch.persistence.room.ColumnInfo
+import android.arch.persistence.room.Entity
+import android.arch.persistence.room.PrimaryKey
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+@Entity(tableName = "TurnMeta")
+class MetaTable {
+ @PrimaryKey(autoGenerate = true)
+ var id: Long = 0
+
+ @ColumnInfo(name = "player")
+ var playerId: Long = -1
+
+ @ColumnInfo(name = "game")
+ var gameId: Long = -1
+
+ @ColumnInfo(name = "turn")
+ var turnId: Long = -1
+
+ @ColumnInfo(name = "leg")
+ var legNumber: Int = -1
+
+ @ColumnInfo(name = "set")
+ var setNumber: Int = -1
+
+ @ColumnInfo(name = "turnInLeg")
+ var turnInLeg: Int = -1
+
+ @ColumnInfo(name = "score")
+ var score: Int = -1
+
+ @ColumnInfo(name = "atco")
+ var atCheckout: Int = 0
+
+ @ColumnInfo(name = "started")
+ var started: Boolean = false
+
+ @ColumnInfo(name = "break")
+ var breakMade: Boolean = false
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalPlayerRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/player/LocalPlayerRepository.kt
similarity index 86%
rename from android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalPlayerRepository.kt
rename to android/DartsScorecard/data/src/main/java/nl/entreco/data/db/player/LocalPlayerRepository.kt
index 43e96203..a844aebd 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalPlayerRepository.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/player/LocalPlayerRepository.kt
@@ -1,10 +1,8 @@
-package nl.entreco.data.play.repository
+package nl.entreco.data.db.player
import android.support.annotation.WorkerThread
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.db.Mapper
-import nl.entreco.data.db.player.PlayerDao
-import nl.entreco.data.db.player.PlayerTable
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.repository.PlayerRepository
@@ -29,11 +27,13 @@ class LocalPlayerRepository(db: DscDatabase, private val mapper: Mapper {
val table = playerDao.fetchAll()
return mapper.to(table)
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/stats/LocalStatRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/stats/LocalStatRepository.kt
new file mode 100644
index 00000000..bce86704
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/stats/LocalStatRepository.kt
@@ -0,0 +1,29 @@
+package nl.entreco.data.db.stats
+
+import android.support.annotation.WorkerThread
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.domain.model.Stat
+import nl.entreco.domain.repository.StatRepository
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+class LocalStatRepository(db: DscDatabase, private val mapper: StatMapper) : StatRepository {
+
+ private val turnDao = db.turnDao()
+ private val metaDao = db.metaDao()
+
+ @WorkerThread
+ override fun fetchAllForGame(gameId: Long): Map {
+ val turnTable = turnDao.fetchAll(gameId)
+ val metaTable = metaDao.fetchAll(gameId)
+ return mapper.to(turnTable, metaTable)
+ }
+
+ @WorkerThread
+ override fun fetchStat(turnId: Long, metaId: Long): Stat {
+ val turnTable = turnDao.fetchById(turnId)
+ val metaTable = metaDao.fetchById(metaId)
+ return mapper.to(turnTable, metaTable)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/stats/StatMapper.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/stats/StatMapper.kt
new file mode 100644
index 00000000..49668707
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/stats/StatMapper.kt
@@ -0,0 +1,38 @@
+package nl.entreco.data.db.stats
+
+import nl.entreco.data.db.meta.MetaTable
+import nl.entreco.data.db.turn.TurnMapper
+import nl.entreco.data.db.turn.TurnTable
+import nl.entreco.domain.model.Stat
+import nl.entreco.domain.model.Turn
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+class StatMapper {
+
+ fun to(turns: List, metas: List): Map {
+ val list = HashMap()
+ turns.forEachIndexed { index, turn ->
+ var stat: Stat? = null
+ if (list.containsKey(turn.player)) {
+ stat = list[turn.player]
+ }
+ list[turn.player] = to(turn, metas[index]) + stat
+ }
+ return list
+ }
+
+ fun to(turn: TurnTable, meta: MetaTable): Stat {
+ val t = TurnMapper().to(turn)
+ val n180 = if (t.total() == 180) 1 else 0
+ val n140 = if (t.total() in 140..179) 1 else 0
+ val n100 = if (t.total() in 100..139) 1 else 0
+ val checkout = if (didFinish(t, meta)) 1 else 0
+ val highCo = if (didFinish(t, meta)) listOf(t.total()) else emptyList()
+ val breaks = if (meta.breakMade) 1 else 0
+ return Stat(turn.player, t.total(), t.dartsUsed(), n180, n140, n100, meta.atCheckout, checkout, breaks, listOf(t.total()), highCo)
+ }
+
+ private fun didFinish(t: Turn, meta: MetaTable) = t.total() == meta.score
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/LocalTurnRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/LocalTurnRepository.kt
new file mode 100644
index 00000000..fb6b4c6b
--- /dev/null
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/LocalTurnRepository.kt
@@ -0,0 +1,33 @@
+package nl.entreco.data.db.turn
+
+import android.support.annotation.WorkerThread
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.repository.TurnRepository
+
+/**
+ * Created by Entreco on 23/12/2017.
+ */
+class LocalTurnRepository(db: DscDatabase, private val mapper: TurnMapper) : TurnRepository {
+
+ private val turnDao = db.turnDao()
+
+ @WorkerThread
+ override fun store(gameId: Long, playerId: Long, turn: Turn): Long {
+ val table = mapper.from(gameId, playerId, turn)
+ return turnDao.create(table)
+ }
+
+ @WorkerThread
+ override fun fetchTurnsForGame(gameId: Long): List> {
+ val map = mutableListOf>()
+ val turnsInGame = turnDao.fetchAll(gameId)
+ turnsInGame.forEach { map.add(Pair(it.player, mapper.to(it))) }
+ return map
+ }
+
+ @WorkerThread
+ override fun undo(gameId: Long): Int {
+ return turnDao.undoLast(gameId)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnDao.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnDao.kt
index cae0afed..e9cef4dd 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnDao.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnDao.kt
@@ -13,6 +13,12 @@ interface TurnDao {
@Query("SELECT * FROM Turn WHERE game = :gameId")
fun fetchAll(gameId: Long): List
+ @Query("SELECT * FROM Turn WHERE id = :turnId")
+ fun fetchById(turnId: Long): TurnTable
+
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun create(turn: TurnTable): Long
+
+ @Query("DELETE FROM Turn WHERE game = :gameId AND id = (SELECT MAX(id) FROM Turn)")
+ fun undoLast(gameId: Long): Int
}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnMapper.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnMapper.kt
index 1eeaf00d..e8f3bbba 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnMapper.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnMapper.kt
@@ -17,9 +17,10 @@ class TurnMapper : Mapper {
}
}
- fun from(gameId: Long, turn: Turn): TurnTable {
+ fun from(gameId: Long, playerId: Long, turn: Turn): TurnTable {
val table = TurnTable()
table.game = gameId
+ table.player = playerId
table.d1 = turn.first().number()
table.m1 = turn.first().multiplier()
table.d2 = turn.second().number()
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnTable.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnTable.kt
index bfa1710f..1e423e5a 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnTable.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/db/turn/TurnTable.kt
@@ -13,19 +13,21 @@ class TurnTable {
var id: Long = 0
@ColumnInfo(name = "d1")
- var d1: Int = 0
+ var d1: Int = -1
@ColumnInfo(name = "d2")
- var d2: Int = 0
+ var d2: Int = -1
@ColumnInfo(name = "d3")
- var d3: Int = 0
+ var d3: Int = -1
@ColumnInfo(name = "m1")
- var m1: Int = 0
+ var m1: Int = -1
@ColumnInfo(name = "m2")
- var m2: Int = 0
+ var m2: Int = -1
@ColumnInfo(name = "m3")
- var m3: Int = 0
+ var m3: Int = -1
@ColumnInfo(name = "numDarts")
- var numDarts: Int = 0
+ var numDarts: Int = -1
@ColumnInfo(name = "game")
- var game: Long = 0
+ var game: Long = -1
+ @ColumnInfo(name = "player")
+ var player: Long = -1
}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalGameRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalGameRepository.kt
deleted file mode 100644
index 248a3ab1..00000000
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalGameRepository.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package nl.entreco.data.play.repository
-
-import android.support.annotation.WorkerThread
-import nl.entreco.data.DscDatabase
-import nl.entreco.data.db.Mapper
-import nl.entreco.data.db.game.GameDao
-import nl.entreco.data.db.game.GameTable
-import nl.entreco.domain.model.Game
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.launch.FetchLatestGameResponse
-import nl.entreco.domain.repository.GameRepository
-import nl.entreco.domain.repository.TeamIdsString
-
-/**
- * Created by Entreco on 15/11/2017.
- */
-class LocalGameRepository(db: DscDatabase, private val mapper: Mapper) : GameRepository {
-
- private val gameDao: GameDao = db.gameDao()
-
- @Throws
- @WorkerThread
- override fun create(teams: String, startScore: Int, startIndex: Int, numLegs: Int, numSets: Int): Long {
- val table = GameTable()
-
- table.teams = teams
- table.numLegs = numLegs
- table.numSets = numSets
- table.startIndex = startIndex
- table.startScore = startScore
-
- return gameDao.create(table)
- }
-
- @WorkerThread
- override fun fetchBy(id: Long): Game {
- val gameTable = gameDao.fetchBy(id) ?: throw IllegalStateException("Game $id does not exist")
- return mapper.to(gameTable)
- }
-
- @WorkerThread
- override fun fetchLatest(): FetchLatestGameResponse {
- val all = gameDao.fetchAll()
- return if (all.isEmpty()) throw IllegalStateException("no Games found")
- else {
- val latestGame = all[0]
- FetchLatestGameResponse(latestGame.id, TeamIdsString(latestGame.teams), CreateGameRequest(latestGame.startScore, latestGame.startIndex, latestGame.numLegs, latestGame.numSets))
- }
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalTurnRepository.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalTurnRepository.kt
deleted file mode 100644
index c1ecb37c..00000000
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/play/repository/LocalTurnRepository.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package nl.entreco.data.play.repository
-
-import android.support.annotation.WorkerThread
-import nl.entreco.data.DscDatabase
-import nl.entreco.data.db.turn.TurnMapper
-import nl.entreco.domain.model.Turn
-import nl.entreco.domain.repository.TurnRepository
-
-/**
- * Created by Entreco on 23/12/2017.
- */
-class LocalTurnRepository(db: DscDatabase, private val mapper: TurnMapper) : TurnRepository {
-
- private val turnDao = db.turnDao()
-
- @WorkerThread
- override fun store(gameId: Long, turn: Turn) {
- val table = mapper.from(gameId, turn)
- turnDao.create(table)
- }
-
- @WorkerThread
- override fun fetchTurnsForGame(gameId: Long): List {
- val turnsInGame = turnDao.fetchAll(gameId)
- return mapper.to(turnsInGame)
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/main/java/nl/entreco/data/setup/repository/SharedPreferenceRepo.kt b/android/DartsScorecard/data/src/main/java/nl/entreco/data/prefs/SharedPreferenceRepo.kt
similarity index 89%
rename from android/DartsScorecard/data/src/main/java/nl/entreco/data/setup/repository/SharedPreferenceRepo.kt
rename to android/DartsScorecard/data/src/main/java/nl/entreco/data/prefs/SharedPreferenceRepo.kt
index 4284068e..237d8456 100644
--- a/android/DartsScorecard/data/src/main/java/nl/entreco/data/setup/repository/SharedPreferenceRepo.kt
+++ b/android/DartsScorecard/data/src/main/java/nl/entreco/data/prefs/SharedPreferenceRepo.kt
@@ -1,9 +1,9 @@
-package nl.entreco.data.setup.repository
+package nl.entreco.data.prefs
import android.content.SharedPreferences
import nl.entreco.domain.repository.PreferenceRepository
-import nl.entreco.domain.setup.usecase.FetchSettingsResponse
-import nl.entreco.domain.setup.usecase.StoreSettingsRequest
+import nl.entreco.domain.setup.settings.FetchSettingsResponse
+import nl.entreco.domain.setup.settings.StoreSettingsRequest
/**
* Created by entreco on 04/01/2018.
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/game/GameMapperTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/game/GameMapperTest.kt
index cb3a9e8e..e52e5d0b 100644
--- a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/game/GameMapperTest.kt
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/game/GameMapperTest.kt
@@ -23,12 +23,12 @@ class GameMapperTest {
@Test
fun `should create Game with all values set (except teams)`() {
- givenGameTable(id = 1, teams = "1,2|3,4", numLegs = 100, numSets = 1000, startScore = 42, startIndex = 18)
+ givenGameTable(id = 1, teams = "1,2|3,4", numLegs = 100, numSets = 1000, startScore = 42, startIndex = 18, finished = true)
whenConverting()
assertEquals(1, actualGame.id)
}
- private fun givenGameTable(id: Long = 0, teams: String = "", numLegs: Int = 0, numSets: Int = 0, startScore: Int = 0, startIndex: Int = 0) {
+ private fun givenGameTable(id: Long = 0, teams: String = "", numLegs: Int = 0, numSets: Int = 0, startScore: Int = 0, startIndex: Int = 0, finished: Boolean = false) {
val table = GameTable()
table.id = id
table.teams = teams
@@ -36,6 +36,7 @@ class GameMapperTest {
table.numSets = numSets
table.startScore = startScore
table.startIndex = startIndex
+ table.finished = finished
givenTabel = table
}
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/meta/LocalMetaRepositoryTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/meta/LocalMetaRepositoryTest.kt
new file mode 100644
index 00000000..4dd52049
--- /dev/null
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/meta/LocalMetaRepositoryTest.kt
@@ -0,0 +1,51 @@
+package nl.entreco.data.db.meta
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.domain.model.TurnMeta
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 24/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class LocalMetaRepositoryTest {
+
+ @Mock private lateinit var mockDb: DscDatabase
+ @Mock private lateinit var mockMetaDao: MetaDao
+ @Mock private lateinit var mockMapper: MetaMapper
+ @Mock private lateinit var mockMeta: TurnMeta
+ @Mock private lateinit var mockTable: MetaTable
+ private lateinit var subject: LocalMetaRepository
+
+ @Before
+ fun setUp() {
+ whenever(mockDb.metaDao()).thenReturn(mockMetaDao)
+ subject = LocalMetaRepository(mockDb, mockMapper)
+ }
+
+ @Test
+ fun `it should use mapper when creating meta`() {
+ subject.create(1, 3, mockMeta, 5)
+ verify(mockMapper).from(3, 1, mockMeta, 5)
+ }
+
+ @Test
+ fun `it should use metaDao when creating meta`() {
+ whenever(mockMapper.from(any(), any(), any(), any())).thenReturn(mockTable)
+ subject.create(1, 3, mockMeta, 5)
+ verify(mockMetaDao).create(mockTable)
+ }
+
+ @Test
+ fun `it should undo`() {
+ subject.undo(5)
+ verify(mockMetaDao).undoLast(5)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/meta/MetaMapperTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/meta/MetaMapperTest.kt
new file mode 100644
index 00000000..780a4c8e
--- /dev/null
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/meta/MetaMapperTest.kt
@@ -0,0 +1,53 @@
+package nl.entreco.data.db.meta
+
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.TurnMeta
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class MetaMapperTest {
+
+ @Mock
+ private lateinit var mockTurnMeta : TurnMeta
+
+ private val givenGameId : Long = 32
+ private val givenTurnId : Long = 1688
+ private val givenAtDouble : Int = 800
+
+
+ private val givenPlayerId : Long = 33
+ private val givenTurnNumber : Int = 11
+ private val givenScore : Score = Score(102, 4, 5)
+ private val givenStarted = true
+ private val givenBreakMade = true
+
+ private val givenMeta : TurnMeta = TurnMeta(givenPlayerId, givenTurnNumber, givenScore, givenStarted, givenBreakMade)
+ private val subject = MetaMapper()
+
+ @Test
+ fun from() {
+ val result = subject.from(givenGameId, givenTurnId, givenMeta, givenAtDouble)
+ assertEquals(givenTurnId, result.turnId)
+ assertEquals(givenGameId, result.gameId)
+ assertEquals(givenPlayerId, result.playerId)
+ assertEquals(givenScore.leg, result.legNumber)
+ assertEquals(givenScore.set, result.setNumber)
+ assertEquals(givenScore.score, result.score)
+ assertEquals(givenTurnNumber, result.turnInLeg)
+ assertEquals(givenAtDouble, result.atCheckout)
+ assertEquals(true, result.started)
+ assertEquals(true, result.breakMade)
+ }
+
+ @Test(expected = NotImplementedError::class)
+ fun `to not implemented`() {
+ subject.to(mockTurnMeta)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/stats/LocalStatRepositoryTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/stats/LocalStatRepositoryTest.kt
new file mode 100644
index 00000000..f44567b3
--- /dev/null
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/stats/LocalStatRepositoryTest.kt
@@ -0,0 +1,53 @@
+package nl.entreco.data.db.stats
+
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.meta.MetaDao
+import nl.entreco.data.db.turn.TurnDao
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyList
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 24/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class LocalStatRepositoryTest {
+
+ @Mock private lateinit var mockDb: DscDatabase
+ @Mock private lateinit var mockMapper: StatMapper
+ @Mock private lateinit var mockTurnDao: TurnDao
+ @Mock private lateinit var mockMetaDao: MetaDao
+ private lateinit var subject: LocalStatRepository
+
+ @Before
+ fun setUp() {
+ givenSubject()
+ }
+
+ private fun givenSubject() {
+ whenever(mockDb.turnDao()).thenReturn(mockTurnDao)
+ whenever(mockDb.metaDao()).thenReturn(mockMetaDao)
+ subject = LocalStatRepository(mockDb, mockMapper)
+ }
+
+ @Test
+ fun fetchAllForGame() {
+ subject.fetchAllForGame(2)
+ verify(mockTurnDao).fetchAll(2)
+ verify(mockMetaDao).fetchAll(2)
+ verify(mockMapper).to(anyList(), anyList())
+ }
+
+ @Test
+ fun fetchStat() {
+ subject.fetchStat(12, 14)
+ verify(mockTurnDao).fetchById(12)
+ verify(mockMetaDao).fetchById(14)
+ }
+
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/stats/StatMapperTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/stats/StatMapperTest.kt
new file mode 100644
index 00000000..45b9e089
--- /dev/null
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/stats/StatMapperTest.kt
@@ -0,0 +1,219 @@
+package nl.entreco.data.db.stats
+
+import nl.entreco.data.db.meta.MetaMapper
+import nl.entreco.data.db.meta.MetaTable
+import nl.entreco.data.db.turn.TurnMapper
+import nl.entreco.data.db.turn.TurnTable
+import nl.entreco.domain.model.*
+import nl.entreco.domain.play.ScoreEstimator
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Created by entreco on 20/01/2018.
+ */
+class StatMapperTest {
+
+ private lateinit var subject: StatMapper
+ private lateinit var givenScores: Map
+ private lateinit var givenTurns: List
+ private lateinit var givenPlayerIds: List
+ private lateinit var givenMetas: List
+ private val gameId: Long = 3
+ private val turnMapper = TurnMapper()
+ private val metaMapper = MetaMapper()
+ private lateinit var expectedStats: Map
+ private val scoreEstimator = ScoreEstimator()
+
+ @Test
+ fun `it should calculate correct stats for player1 first turn`() {
+ givenSubject()
+ givenPlayers(1, 2)
+ givenTurns(`100`(), `60`())
+ whenConverting()
+
+ thenAvgIs(1, 100.toDouble())
+ then100sIs(1, 1)
+ then140sIs(1, 0)
+ then180sIs(1, 0)
+ thenHighestIs(1, 100)
+ }
+
+ @Test
+ fun `it should calculate correct stats for player1 second turn`() {
+ givenSubject()
+ givenPlayers(1, 2)
+ givenTurns(`100`(), `60`(), `180`())
+ whenConverting()
+
+ thenAvgIs(1, 140.toDouble())
+ then100sIs(1, 1)
+ then140sIs(1, 0)
+ then180sIs(1, 1)
+ thenHighestIs(1, 180)
+ }
+
+ @Test
+ fun `it should calculate correct stats for player2 first turn`() {
+ givenSubject()
+ givenPlayers(1, 2)
+ givenTurns(`100`(), `60`())
+ whenConverting()
+
+ thenAvgIs(2, 60.toDouble())
+ then100sIs(2, 0)
+ then140sIs(2, 0)
+ then180sIs(2, 0)
+ thenHighestIs(2, 60)
+ }
+
+ @Test
+ fun `it should calculate correct finishes for player1`() {
+ givenSubject()
+ givenPlayers(1)
+ givenTurns(`180`(), `180`(), `100`(), `41`())
+ whenConverting()
+
+ thenCheckOutIs(1, 1.0)
+ thenHighestCheckOutIs(1, 41)
+ }
+
+ @Test
+ fun `it should calculate correct Doubles for player1`() {
+ givenSubject()
+ givenPlayers(1)
+ givenTurns(`180`(), `180`(), `100`(), `41`())
+ whenConverting()
+
+ thenAtDoubleIs(1, 1)
+ }
+
+ @Test
+ fun `it should calculate correct Doubles for player1 - multiple`() {
+ givenSubject()
+ givenPlayers(1)
+ givenTurns(`180`(), `180`(), `60`(), `60`(), Turn(Dart.SINGLE_1, Dart.ZERO, Dart.ZERO))
+ whenConverting()
+
+ thenAtDoubleIs(1, 2)
+ }
+
+ @Test
+ fun `it should calculate correct breaksMade for player1`() {
+ givenSubject()
+ givenPlayers(1)
+ givenTurns(`180`(), `180`(), `100`(), `41`())
+ whenConverting()
+
+ thenBreaksMadeIs(1, 0)
+ }
+
+ @Test
+ fun `it should calculate correct breaksMade for player2`() {
+ givenSubject()
+ givenPlayers(1, 2)
+ givenTurns(`60`(), `180`(), `60`(), `180`(), `60`(), `141`())
+ whenConverting()
+
+ thenBreaksMadeIs(1, 0)
+ thenBreaksMadeIs(2, 1)
+ }
+
+ private fun givenSubject() {
+ subject = StatMapper()
+ }
+
+ private fun givenPlayers(vararg ids: Long) {
+ givenPlayerIds = ids.toList()
+ val scores = emptyMap().toMutableMap()
+ ids.forEach {
+ scores[it] = Score()
+ }
+ givenScores = scores
+ }
+
+ private fun givenTurns(vararg turns: Turn) {
+ val metaTables = mutableListOf()
+ val turnTables = mutableListOf()
+ var starter = true
+ val starterId = id(0)
+
+ turns.forEachIndexed { index, turn ->
+ val playerId = id(index)
+ turnTables.add(toTable(playerId, turn))
+
+ val score = givenScores[playerId]!!
+ val previousScore = score.copy()
+ val atDouble = scoreEstimator.atDouble(turn, score.score)
+ score -= turn
+
+ val meta = TurnMeta(id(index), index, previousScore, starter, score.score ==0 && playerId != starterId)
+ metaTables.add(toTable(playerId, atDouble, meta))
+ starter = false
+ }
+ givenTurns = turnTables
+ givenMetas = metaTables
+ }
+
+ private fun whenConverting() {
+ expectedStats = subject.to(givenTurns, givenMetas)
+ }
+
+ private fun thenAvgIs(playerId: Long, expected: Double) {
+ val score = expectedStats[playerId]!!.totalScore
+ val darts = expectedStats[playerId]!!.nDarts
+ assertEquals(expected, (score / darts.toDouble()) * 3.0, 0.1)
+ }
+
+ private fun then100sIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.n100)
+ }
+
+ private fun then140sIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.n140)
+ }
+
+ private fun then180sIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.n180)
+ }
+
+ private fun thenHighestIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.highest[0])
+ }
+
+ private fun thenCheckOutIs(playerId: Long, expected: Double) {
+ val co = expectedStats[playerId]!!.nCheckouts
+ val count = expectedStats[playerId]!!.nAtCheckout
+ assertEquals(expected, co / count.toDouble(), 0.1)
+ }
+
+ private fun thenHighestCheckOutIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.highestCo[0])
+ }
+
+ private fun thenAtDoubleIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.nAtCheckout)
+ }
+
+ private fun thenBreaksMadeIs(playerId: Long, expected: Int) {
+ assertEquals(expected, expectedStats[playerId]!!.nBreaks)
+ }
+
+ private fun `180`(): Turn = Turn(Dart.TRIPLE_20, Dart.TRIPLE_20, Dart.TRIPLE_20)
+ private fun `141`(): Turn = Turn(Dart.TRIPLE_20, Dart.TRIPLE_19, Dart.DOUBLE_12)
+ private fun `100`(): Turn = Turn(Dart.TRIPLE_20, Dart.SINGLE_20, Dart.SINGLE_20)
+ private fun `60`(): Turn = Turn(Dart.SINGLE_20, Dart.SINGLE_20, Dart.SINGLE_20)
+ private fun `41`(): Turn = Turn(Dart.SINGLE_1, Dart.DOUBLE_20)
+
+ private fun id(index: Int): Long {
+ return givenPlayerIds[index % givenPlayerIds.size]
+ }
+
+ private fun toTable(id: Long, turn: Turn): TurnTable {
+ return turnMapper.from(gameId, id, turn)
+ }
+
+ private fun toTable(turnId: Long, atDouble: Int, meta: TurnMeta): MetaTable {
+ return metaMapper.from(gameId, turnId, meta, atDouble)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/turn/TurnMapperTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/turn/TurnMapperTest.kt
index aa1d9cd8..a6e38bb8 100644
--- a/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/turn/TurnMapperTest.kt
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/db/turn/TurnMapperTest.kt
@@ -2,10 +2,9 @@ package nl.entreco.data.db.turn
import nl.entreco.domain.model.Dart
import nl.entreco.domain.model.Turn
+import org.junit.Assert.assertEquals
import org.junit.Test
-import org.junit.Assert.*
-
/**
* Created by Entreco on 24/12/2017.
*/
@@ -13,6 +12,7 @@ class TurnMapperTest {
private val subject = TurnMapper()
private val gameId : Long = 1011
+ private val playerId : Long = 42
private lateinit var expectedTurn : Turn
@Test
@@ -42,7 +42,7 @@ class TurnMapperTest {
}
private fun whenConvertingFromAndTo(turn: Turn) {
- expectedTurn = subject.to(subject.from(gameId, turn))
+ expectedTurn = subject.to(subject.from(gameId, playerId, turn))
assertEquals("turn: $turn exp:$expectedTurn",turn, expectedTurn)
}
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalGameRepositoryTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalGameRepositoryTest.kt
similarity index 76%
rename from android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalGameRepositoryTest.kt
rename to android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalGameRepositoryTest.kt
index 51cd13fa..081041ac 100644
--- a/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalGameRepositoryTest.kt
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalGameRepositoryTest.kt
@@ -1,12 +1,14 @@
-package nl.entreco.data.play.repository
+package nl.entreco.data.play.local
import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.isA
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
import nl.entreco.data.db.game.GameDao
import nl.entreco.data.db.game.GameMapper
import nl.entreco.data.db.game.GameTable
+import nl.entreco.data.db.game.LocalGameRepository
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
@@ -65,6 +67,20 @@ class LocalGameRepositoryTest {
whenFetchingByUid(2)
}
+ @Test
+ fun `it should mark game as finished`() {
+ givenExistingGames(1)
+ whenFinishingGame(1)
+ thenUpdateGamesIsCalledOnDao()
+ }
+
+ @Test
+ fun `it should unmark game as finished`() {
+ givenExistingGames(1)
+ whenUnFinishingGame(1)
+ thenUndoFinishIsCalledOnDao()
+ }
+
private fun givenExistingGames(){
val table = GameTable()
table.startIndex = 0
@@ -100,6 +116,14 @@ class LocalGameRepositoryTest {
subject.fetchBy(id)
}
+ private fun whenFinishingGame(gameId: Long) {
+ subject.finish(gameId)
+ }
+
+ private fun whenUnFinishingGame(gameId: Long) {
+ subject.undoFinish(gameId)
+ }
+
private fun thenFetchAllIsCalledOnDao() {
verify(mockGameDao).fetchAll()
}
@@ -107,4 +131,12 @@ class LocalGameRepositoryTest {
private fun thenFetchByUidIsCalledOnDao() {
verify(mockGameDao).fetchBy(any())
}
+
+ private fun thenUpdateGamesIsCalledOnDao(){
+ verify(mockGameDao).updateGames(isA())
+ }
+
+ private fun thenUndoFinishIsCalledOnDao(){
+ verify(mockGameDao).undoFinish(isA())
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalPlayerRepositoryTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalPlayerRepositoryTest.kt
similarity index 96%
rename from android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalPlayerRepositoryTest.kt
rename to android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalPlayerRepositoryTest.kt
index 70261e35..f7f3c74a 100644
--- a/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalPlayerRepositoryTest.kt
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalPlayerRepositoryTest.kt
@@ -1,9 +1,10 @@
-package nl.entreco.data.play.repository
+package nl.entreco.data.play.local
import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.player.LocalPlayerRepository
import nl.entreco.data.db.player.PlayerDao
import nl.entreco.data.db.player.PlayerMapper
import nl.entreco.data.db.player.PlayerTable
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalTurnRepositoryTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalTurnRepositoryTest.kt
similarity index 70%
rename from android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalTurnRepositoryTest.kt
rename to android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalTurnRepositoryTest.kt
index 3900a04d..30b8526e 100644
--- a/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/repository/LocalTurnRepositoryTest.kt
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/play/local/LocalTurnRepositoryTest.kt
@@ -1,8 +1,9 @@
-package nl.entreco.data.play.repository
+package nl.entreco.data.play.local
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.data.DscDatabase
+import nl.entreco.data.db.DscDatabase
+import nl.entreco.data.db.turn.LocalTurnRepository
import nl.entreco.data.db.turn.TurnDao
import nl.entreco.data.db.turn.TurnMapper
import nl.entreco.data.db.turn.TurnTable
@@ -23,9 +24,10 @@ class LocalTurnRepositoryTest {
@Mock private lateinit var mockTurnDao: TurnDao
@Mock private lateinit var mockMapper: TurnMapper
private lateinit var subject: LocalTurnRepository
- private val gameId : Long = 11
- private lateinit var givenTurn : Turn
- private lateinit var expectedTable : TurnTable
+ private val gameId: Long = 11
+ private val playerId: Long = 1066654
+ private lateinit var givenTurn: Turn
+ private lateinit var expectedTable: TurnTable
@Before
fun setUp() {
@@ -45,24 +47,30 @@ class LocalTurnRepositoryTest {
fun fetchTurnsForGame() {
whenFetchingTurns()
thenFetchIsCalledOnDao()
- andMapperConvertsTo()
+ }
+
+ @Test
+ fun `it should undo`() {
+ subject.undo(5)
+ verify(mockTurnDao).undoLast(5)
}
private fun givenTurn(turn: Turn) {
givenTurn = turn
- expectedTable = TurnMapper().from(gameId, givenTurn)
+ expectedTable = TurnMapper().from(gameId, playerId, givenTurn)
}
private fun whenStoring() {
- whenever(mockMapper.from(gameId, givenTurn)).thenReturn(expectedTable)
- subject.store(gameId, givenTurn)
+ whenever(mockMapper.from(gameId, playerId, givenTurn)).thenReturn(expectedTable)
+ subject.store(gameId, playerId, givenTurn)
}
+
private fun whenFetchingTurns() {
subject.fetchTurnsForGame(gameId)
}
private fun thenMapperConvertsFrom() {
- verify(mockMapper).from(gameId, givenTurn)
+ verify(mockMapper).from(gameId, playerId, givenTurn)
}
private fun thenFetchIsCalledOnDao() {
@@ -72,9 +80,4 @@ class LocalTurnRepositoryTest {
private fun andCreateIsCalled() {
verify(mockTurnDao).create(expectedTable)
}
-
- private fun andMapperConvertsTo() {
- verify(mockMapper).to(emptyList())
- }
-
}
\ No newline at end of file
diff --git a/android/DartsScorecard/data/src/test/java/nl/entreco/data/setup/repository/SharedPreferenceRepoTest.kt b/android/DartsScorecard/data/src/test/java/nl/entreco/data/setup/repository/SharedPreferenceRepoTest.kt
index ffa2fd71..74b2b189 100644
--- a/android/DartsScorecard/data/src/test/java/nl/entreco/data/setup/repository/SharedPreferenceRepoTest.kt
+++ b/android/DartsScorecard/data/src/test/java/nl/entreco/data/setup/repository/SharedPreferenceRepoTest.kt
@@ -3,8 +3,9 @@ package nl.entreco.data.setup.repository
import android.content.SharedPreferences
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.setup.usecase.FetchSettingsResponse
-import nl.entreco.domain.setup.usecase.StoreSettingsRequest
+import nl.entreco.data.prefs.SharedPreferenceRepo
+import nl.entreco.domain.setup.settings.FetchSettingsResponse
+import nl.entreco.domain.setup.settings.StoreSettingsRequest
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
@@ -34,7 +35,7 @@ class SharedPreferenceRepoTest {
@Test
fun storePreferredSetup() {
givenSubject()
- whenStoringPreferredSetup(StoreSettingsRequest(1,2,3,4,5))
+ whenStoringPreferredSetup(StoreSettingsRequest(1, 2, 3, 4, 5))
thenCorrectValuesAreStored()
}
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/BaseUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/BaseUsecase.kt
index f40affd0..456eb817 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/BaseUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/BaseUsecase.kt
@@ -1,7 +1,7 @@
package nl.entreco.domain
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
/**
* Created by Entreco on 17/12/2017.
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/Background.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/Background.kt
similarity index 77%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/Background.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/Background.kt
index 6d558935..0aa33473 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/Background.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/Background.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
import java.util.concurrent.Future
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/BgExecutor.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/BgExecutor.kt
similarity index 89%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/BgExecutor.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/BgExecutor.kt
index aa43aeb1..4a66a13a 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/BgExecutor.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/BgExecutor.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/FgExecutor.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/FgExecutor.kt
similarity index 85%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/FgExecutor.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/FgExecutor.kt
index 44c8ade9..7ea9c990 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/FgExecutor.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/FgExecutor.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
import android.os.Handler
import android.os.Looper
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/Foreground.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/Foreground.kt
similarity index 69%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/Foreground.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/Foreground.kt
index 89f8e2c7..bb2be116 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/executors/Foreground.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/common/executors/Foreground.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
/**
* Created by Entreco on 12/12/2017.
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/TeamNamesString.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsRequest.kt
similarity index 93%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/TeamNamesString.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsRequest.kt
index 65fc2c65..c8830b46 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/TeamNamesString.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsRequest.kt
@@ -4,10 +4,9 @@ import nl.entreco.domain.model.players.PlayerSeperator
import nl.entreco.domain.model.players.TeamSeperator
/**
- * Created by Entreco on 16/12/2017.
+ * Created by entreco on 06/01/2018.
*/
-data class TeamNamesString(private val teamString: String) {
-
+data class ExtractTeamsRequest(private val teamString: String){
private val illegalState = IllegalStateException("invalid team string, should be 'player1,player2|player3|player4,player5'")
private val playerSplit: MutableList> = emptyList>().toMutableList()
private lateinit var teamSplit: List
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsResponse.kt
new file mode 100644
index 00000000..301ee678
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsResponse.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.launch
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class ExtractTeamsResponse(val teamNames: String)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/ExtractTeamsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsUsecase.kt
similarity index 64%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/ExtractTeamsUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsUsecase.kt
index 9ef95f8c..83d79af1 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/ExtractTeamsUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/ExtractTeamsUsecase.kt
@@ -1,12 +1,10 @@
-package nl.entreco.domain.launch.usecase
+package nl.entreco.domain.launch
import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.launch.TeamNamesString
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.repository.PlayerRepository
-import nl.entreco.domain.repository.TeamIdsString
import javax.inject.Inject
/**
@@ -14,14 +12,14 @@ import javax.inject.Inject
*/
class ExtractTeamsUsecase @Inject constructor(private val playerRepository: PlayerRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
- fun exec(teamNamesInput: TeamNamesString, done: (TeamIdsString) -> Unit, fail: (Throwable) -> Unit) {
+ fun exec(request: ExtractTeamsRequest, done: (ExtractTeamsResponse) -> Unit, fail: (Throwable) -> Unit) {
onBackground({
- var teamIds = teamNamesInput.toString()
- teamNamesInput.toPlayerNames().forEach {
+ var teamIds = request.toString()
+ request.toPlayerNames().forEach {
val player = playerRepository.fetchByName(it)
teamIds = replaceNameWithId(player, it, teamIds)
}
- onUi { done(TeamIdsString(teamIds)) }
+ onUi { done(ExtractTeamsResponse(teamIds)) }
}, fail)
}
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/FetchLatestGameResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/FetchLatestGameResponse.kt
index 4477291e..5eb612a7 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/FetchLatestGameResponse.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/FetchLatestGameResponse.kt
@@ -1,9 +1,6 @@
package nl.entreco.domain.launch
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.TeamIdsString
-
/**
* Created by Entreco on 19/12/2017.
*/
-data class FetchLatestGameResponse(val gameId: Long, val teamIds: TeamIdsString, val request: CreateGameRequest)
\ No newline at end of file
+data class FetchLatestGameResponse(val gameId: Long, val teamIds: String, val startScore: Int, val startIndex: Int, val numLegs: Int, val numSets: Int)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/RetrieveLatestGameUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/RetrieveLatestGameUsecase.kt
similarity index 73%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/RetrieveLatestGameUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/RetrieveLatestGameUsecase.kt
index e18023c1..d50ad568 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/RetrieveLatestGameUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/RetrieveLatestGameUsecase.kt
@@ -1,9 +1,8 @@
-package nl.entreco.domain.launch.usecase
+package nl.entreco.domain.launch
import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.launch.FetchLatestGameResponse
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
import nl.entreco.domain.repository.GameRepository
import javax.inject.Inject
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/CreateGameUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/CreateGameUsecase.kt
deleted file mode 100644
index 111a5c01..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/launch/usecase/CreateGameUsecase.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-package nl.entreco.domain.launch.usecase
-
-import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.GameRepository
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
-import javax.inject.Inject
-
-/**
- * Created by Entreco on 12/12/2017.
- */
-class CreateGameUsecase @Inject constructor(private val gameRepository: GameRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
-
- fun exec(modelCreate: CreateGameRequest, teamIds: TeamIdsString, done: (RetrieveGameRequest) -> Unit, fail: (Throwable) -> Unit) {
- onBackground({
- val (score, index, legs, sets) = modelCreate
- val id = gameRepository.create(teamIds.toString(), score, index, legs, sets)
- onUi { done(RetrieveGameRequest(id, teamIds, modelCreate)) }
- }, fail)
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Game.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Game.kt
index 700fe5e8..cf9f807b 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Game.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Game.kt
@@ -1,22 +1,62 @@
package nl.entreco.domain.model
+import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
import nl.entreco.domain.play.Arbiter
data class Game(val id: Long = 0, val arbiter: Arbiter) {
lateinit var next: Next
+ private lateinit var previousState: State
+ private val starters = emptyList().toMutableList()
+ private var newMatchSetOrLeg: Boolean = false
+
var scores = emptyArray()
get() = arbiter.getScores()
fun start(startIndex: Int, teams: Array): Game {
next = arbiter.start(startIndex, teams)
+ starters.clear()
+ starters.add( 0, next.team)
+ previousState = next.state
+ newMatchSetOrLeg = true
return this
}
fun handle(turn: Turn) {
+ previousState = next.state
if (State.MATCH != next.state) {
next = arbiter.handle(turn, next)
+ updateStartTeam(next)
+ }
+ }
+
+ private fun updateStartTeam(next: Next) {
+ newMatchSetOrLeg = when (next.state) {
+ State.MATCH, State.LEG, State.SET -> {
+ starters.add( 0, next.team)
+ true
+ }
+ else -> {
+ false
+ }
}
}
+
+ fun previousScore(): Score {
+ return arbiter.getPreviousScore()
+ }
+
+ fun isNewMatchLegOrSet(): Boolean {
+ return newMatchSetOrLeg
+ }
+
+ fun getTurnCount(): Int {
+ return arbiter.getTurnCount()
+ }
+
+ fun wasBreakMade(by: Player): Boolean {
+ if(starters.size < 2) return false
+ return newMatchSetOrLeg && !starters[1].contains(by)
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Stat.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Stat.kt
new file mode 100644
index 00000000..d5ae7e09
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Stat.kt
@@ -0,0 +1,39 @@
+package nl.entreco.domain.model
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+data class Stat(val playerId: Long, val totalScore: Int, val nDarts: Int, val n180: Int, val n140: Int, val n100: Int, val nAtCheckout: Int, val nCheckouts : Int, val nBreaks : Int, val highest: List, val highestCo: List) {
+
+ operator fun plus(stat: Stat?): Stat {
+ stat?.let {
+ val high = scoreList(stat)
+ val highCo = checkoutList(stat)
+ return copy(totalScore = totalScore + stat.totalScore,
+ nDarts = nDarts + stat.nDarts,
+ n180 = n180 + stat.n180,
+ n140 = n140 + stat.n140,
+ n100 = n100 + stat.n100,
+ nAtCheckout = nAtCheckout + stat.nAtCheckout,
+ nCheckouts = nCheckouts + stat.nCheckouts,
+ nBreaks = nBreaks + stat.nBreaks,
+ highest = high,
+ highestCo = highCo)
+ }
+ return this
+ }
+
+ private fun scoreList(stat: Stat): List {
+ val high = ArrayList()
+ high.addAll(highest)
+ high.addAll(stat.highest)
+ return high.sorted().reversed()
+ }
+
+ private fun checkoutList(stat: Stat): List {
+ val high = ArrayList()
+ high.addAll(highestCo)
+ high.addAll(stat.highestCo)
+ return high.sorted().reversed()
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Turn.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Turn.kt
index ba5fc4d9..f9c5195b 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Turn.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/Turn.kt
@@ -38,6 +38,10 @@ data class Turn (internal val d1: Dart = Dart.NONE, internal val d2: Dart = Dart
}
}
+ fun dartsUsed() : Int {
+ return 3 - dartsLeft()
+ }
+
fun dartsLeft() : Int {
return when {
d1 == Dart.NONE -> 3
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/TurnMeta.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/TurnMeta.kt
new file mode 100644
index 00000000..b6c76b60
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/TurnMeta.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.model
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+data class TurnMeta(val playerId: Long, val turnNumber: Int = 0, val score: Score, val started: Boolean = false, val breakMade: Boolean = false)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/players/Team.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/players/Team.kt
index bf99ed5e..9f44d7ab 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/players/Team.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/model/players/Team.kt
@@ -51,6 +51,10 @@ class Team(val players: Array = emptyArray()) {
else players[0]
}
+ fun contains(playerId: Long): Boolean {
+ return players.map { it.id }.contains(playerId)
+ }
+
fun contains(player: Player): Boolean {
return players.contains(player)
}
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/Arbiter.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/Arbiter.kt
index 0ce4cfa0..0c8d6618 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/Arbiter.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/Arbiter.kt
@@ -2,8 +2,8 @@ package nl.entreco.domain.play
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.State
+import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.players.Team
const val OK: Int = 1
@@ -12,25 +12,34 @@ const val ERR: Int = -2
class Arbiter(initial: Score) {
- private lateinit var turnHandler: TurnHandler
+ internal lateinit var turnHandler: TurnHandler
+ private lateinit var teams: Array
private var scores: Array = emptyArray()
private val scoreSettings = initial.settings
private val legs = mutableListOf>()
private val sets = mutableListOf>>()
+ private var previousScore = Score()
+ private var turnCounter = 0
fun start(startIndex: Int, teams: Array): Next {
+ this.teams = teams
this.turnHandler = TurnHandler(startIndex, teams)
this.scores = Array(teams.size, { scoreSettings.score().copy() })
+ this.turnCounter = 0
return turnHandler.start(scores[0])
}
fun handle(turn: Turn, next: Next): Next {
val teamIndex = turnHandler.indexOf(next.team)
+ previousScore = scores[teamIndex].copy()
+
when (applyScore(teamIndex, turn)) {
ERR -> return turnHandler.next(scores).copy(state = State.ERR_REQUIRES_DOUBLE)
BUST -> return turnHandler.next(scores).copy(state = State.ERR_BUST)
}
+ turnCounter++
+
if (gameShotAndTheMatch(teamIndex)) return Next(State.MATCH, next.team, teamIndex, next.player, scores[teamIndex])
if (requiresNewSet(teamIndex)) return playerForNewSet()
else if (requiresNewLeg(teamIndex)) return playerForNewLeg()
@@ -39,6 +48,7 @@ class Arbiter(initial: Score) {
}
private fun playerForNewLeg() = turnHandler.nextLeg(scores)
+
private fun playerForNewSet() = turnHandler.nextSet(scores)
private fun gameShotAndTheMatch(currentPlayer: Int): Boolean {
@@ -100,9 +110,9 @@ class Arbiter(initial: Score) {
else -> BUST
}
}
-
private fun legFinished(currentPlayer: Int) = scores[currentPlayer].legFinished()
private fun setFinished(currentPlayer: Int) = scores[currentPlayer].setFinished()
+
private fun matchFinished(currentPlayer: Int) = scores[currentPlayer].matchFinished()
fun getScores(): Array {
@@ -116,4 +126,12 @@ class Arbiter(initial: Score) {
fun getSets(): MutableList>> {
return sets
}
+
+ fun getPreviousScore(): Score {
+ return previousScore.copy()
+ }
+
+ fun getTurnCount(): Int {
+ return turnCounter
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/ScoreEstimator.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/ScoreEstimator.kt
index 4fa52f57..b6760641 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/ScoreEstimator.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/ScoreEstimator.kt
@@ -2,11 +2,12 @@ package nl.entreco.domain.play
import nl.entreco.domain.model.Dart
import nl.entreco.domain.model.Turn
+import javax.inject.Inject
/**
* Created by Entreco on 02/12/2017.
*/
-class ScoreEstimator {
+class ScoreEstimator @Inject constructor() {
fun guess(scored: Int, singles: Boolean): Turn {
return if (singles) guessSingle(scored) else guessThree(scored)
@@ -242,4 +243,18 @@ class ScoreEstimator {
else -> Turn()
}
}
+
+ fun atDouble(turn: Turn, required: Int): Int {
+ if (required > 170) return 0
+ var outs = find(required)
+ outs += find(required - turn.d1.points())
+ outs += find(required - turn.d1.points() - turn.d2.points())
+ return outs
+ }
+
+ private val range = 40 downTo 2 step 2
+ private fun find(required: Int): Int {
+ return if(range.contains(required) || required==50) 1
+ else 0
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/TurnHandler.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/TurnHandler.kt
index 62a7203d..d1e42138 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/TurnHandler.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/TurnHandler.kt
@@ -2,9 +2,9 @@ package nl.entreco.domain.play
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.NoPlayer
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
/**
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishRequest.kt
new file mode 100644
index 00000000..cc706402
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishRequest.kt
@@ -0,0 +1,25 @@
+package nl.entreco.domain.play.finish
+
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.Turn
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class GetFinishRequest(val score: Score, val turn: Turn, private val favDouble: Int) {
+ fun score(): Int {
+ return score.score
+ }
+
+ fun dartsLeft(): Int {
+ return turn.dartsLeft()
+ }
+
+ fun total(): Int {
+ return turn.total()
+ }
+
+ fun double(): Int {
+ return favDouble
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishResponse.kt
new file mode 100644
index 00000000..b57dfa5c
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishResponse.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.finish
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class GetFinishResponse(val finish: String)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishUsecase.kt
new file mode 100644
index 00000000..4e43def6
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/finish/GetFinishUsecase.kt
@@ -0,0 +1,231 @@
+package nl.entreco.domain.play.finish
+
+import android.support.annotation.VisibleForTesting
+import android.support.annotation.WorkerThread
+import nl.entreco.domain.common.executors.Background
+import java.util.concurrent.Future
+import javax.inject.Inject
+
+/**
+ * Created by Entreco on 24/11/2017.
+ */
+class GetFinishUsecase @Inject constructor(private val bg: Background) {
+
+ fun calculate(request: GetFinishRequest, result: (GetFinishResponse) -> Unit): Future<*>? {
+ return bg.post(Runnable {
+ val finish = calculateInBack(request.score(), request.dartsLeft(), request.total(), request.double())
+ result(GetFinishResponse(finish))
+ })
+ }
+
+ private val impossible = arrayOf(169, 168, 166, 165, 163, 162, 159)
+ val notPossible = ""
+
+ @WorkerThread
+ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ fun calculateInBack(score: Int, dartsLeft: Int, total: Int, favDouble: Int): String {
+
+ // Calculate desired target
+ val target = score - total
+
+ // First, handle the obvious cases before we go into recursion ;)
+ if (target > 170) return notPossible
+ if (target <= 1) return notPossible
+ if (impossible.contains(target)) return notPossible
+
+ // Now, hardcode some values that do not need favourite Double, since
+ // it can only be done in 1 way
+ if (require(target, dartsLeft, 170, 3)) return "T20 T20 BULL"
+ if (require(target, dartsLeft, 167, 3)) return "T20 T19 BULL"
+ if (require(target, dartsLeft, 164, 3)) return "T20 T18 BULL"
+ if (require(target, dartsLeft, 161, 3)) return "T20 T17 BULL"
+ if (require(target, dartsLeft, 160, 3)) return "T20 T20 D20"
+ if (require(target, dartsLeft, 158, 3)) return "T20 T20 D19"
+ if (require(target, dartsLeft, 157, 3)) return "T20 T19 D20"
+ if (require(target, dartsLeft, 156, 3)) return "T20 T20 D18"
+ if (require(target, dartsLeft, 155, 3)) return "T20 T19 D19"
+ if (require(target, dartsLeft, 154, 3)) return "T20 T18 D20"
+ if (require(target, dartsLeft, 153, 3)) return "T20 T19 D18"
+ if (require(target, dartsLeft, 152, 3)) return "T20 T20 D16"
+ if (require(target, dartsLeft, 151, 3)) return "T20 T17 D20"
+ if (require(target, dartsLeft, 150, 3)) return "T20 T18 D18"
+ if (require(target, dartsLeft, 149, 3)) return "T20 T19 D16"
+ if (require(target, dartsLeft, 148, 3)) return "T20 T16 D20"
+ if (require(target, dartsLeft, 147, 3)) return "T19 T18 D18"
+ if (require(target, dartsLeft, 146, 3)) return "T20 T18 D16"
+ if (require(target, dartsLeft, 145, 3)) return "T20 T15 D20"
+ if (require(target, dartsLeft, 144, 3)) return "T20 T20 D12"
+ if (require(target, dartsLeft, 143, 3)) return "T20 T17 D16"
+ if (require(target, dartsLeft, 142, 3)) return "T20 T14 D20"
+ if (require(target, dartsLeft, 141, 3)) return "T20 T19 D12"
+ if (require(target, dartsLeft, 140, 3)) return "T20 T16 D16"
+ if (require(target, dartsLeft, 139, 3)) return "T19 T14 D20"
+ if (require(target, dartsLeft, 138, 3)) return "T20 T18 D12"
+ if (require(target, dartsLeft, 137, 3)) return "T19 T16 D16"
+ if (require(target, dartsLeft, 136, 3)) return "T20 T20 D8"
+ if (require(target, dartsLeft, 135, 3)) return "T20 T17 D12"
+ if (require(target, dartsLeft, 134, 3)) return "T20 T14 D16"
+ if (require(target, dartsLeft, 133, 3)) return "T20 T19 D8"
+ if (require(target, dartsLeft, 132, 3)) return "T20 T16 D12"
+ if (require(target, dartsLeft, 131, 3)) return "T20 T13 D16"
+ if (require(target, dartsLeft, 130, 3)) return "T20 20 BULL"
+ if (require(target, dartsLeft, 129, 3)) return "T19 T16 D12"
+ if (require(target, dartsLeft, 128, 3)) return "T18 T14 D16"
+ if (require(target, dartsLeft, 127, 3)) return "T20 T17 D8"
+ if (require(target, dartsLeft, 126, 3)) return "T19 T19 D6"
+ if (require(target, dartsLeft, 125, 3)) return "S.BULL T20 D20"
+ if (require(target, dartsLeft, 124, 3)) return "T20 T16 D8"
+ if (require(target, dartsLeft, 123, 3)) return "T19 T16 D9"
+ if (require(target, dartsLeft, 122, 3)) return "T18 T20 D4"
+ if (require(target, dartsLeft, 121, 3)) return "T17 T10 D20"
+ if (require(target, dartsLeft, 120, 3)) return "T20 20 D20"
+ if (require(target, dartsLeft, 119, 3)) return "T19 T10 D16"
+ if (require(target, dartsLeft, 118, 3)) return "T20 18 D20"
+ if (require(target, dartsLeft, 117, 3)) return "T20 17 D20"
+ if (require(target, dartsLeft, 116, 3)) return "T20 16 D20"
+ if (require(target, dartsLeft, 115, 3)) return "T20 15 D20"
+ if (require(target, dartsLeft, 114, 3)) return "T20 14 D20"
+ if (require(target, dartsLeft, 113, 3)) return "T20 13 D20"
+ if (require(target, dartsLeft, 112, 3)) return "T20 12 D20"
+ if (require(target, dartsLeft, 111, 3)) return "T20 19 D16"
+ if (require(target, dartsLeft, 110, 3)) return "T20 18 D16"
+ if (require(target, dartsLeft, 110, 2)) return "T20 BULL"
+ if (require(target, dartsLeft, 109, 3)) return "T19 20 D16"
+ if (require(target, dartsLeft, 108, 3)) return "T20 16 D16"
+ if (require(target, dartsLeft, 107, 3)) return "T19 18 D16"
+ if (require(target, dartsLeft, 107, 2)) return "T19 BULL"
+ if (require(target, dartsLeft, 106, 3)) return "T20 14 D16"
+ if (require(target, dartsLeft, 105, 3)) return "T19 16 D16"
+ if (require(target, dartsLeft, 104, 3)) return "T18 18 D16"
+ if (require(target, dartsLeft, 104, 2)) return "T18 BULL"
+ if (require(target, dartsLeft, 103, 3)) return "T20 3 D20"
+ if (require(target, dartsLeft, 102, 3)) return "T20 10 D16"
+ if (require(target, dartsLeft, 101, 3)) return "T20 1 D20"
+ if (require(target, dartsLeft, 101, 2)) return "T17 BULL"
+ if (require(target, dartsLeft, 100, 2)) return "T20 D20"
+ if (require(target, dartsLeft, 99, 3)) return "T19 10 D16"
+ if (require(target, dartsLeft, 98, 2)) return "T20 D19"
+ if (require(target, dartsLeft, 97, 2)) return "T19 D20"
+ if (require(target, dartsLeft, 96, 2)) return "T20 D18"
+ if (require(target, dartsLeft, 95, 2)) return "T19 D19"
+ if (require(target, dartsLeft, 94, 2)) return "T18 D20"
+ if (require(target, dartsLeft, 93, 2)) return "T19 D18"
+ if (require(target, dartsLeft, 92, 2)) return "T20 D16"
+ if (require(target, dartsLeft, 91, 2)) return "T17 D20"
+ if (require(target, dartsLeft, 90, 2)) return "T20 D15"
+ if (require(target, dartsLeft, 89, 2)) return "T19 D16"
+ if (require(target, dartsLeft, 88, 2)) return "T16 D20"
+ if (require(target, dartsLeft, 87, 2)) return "T17 D18"
+ if (require(target, dartsLeft, 86, 2)) return "T18 D16"
+ if (require(target, dartsLeft, 85, 2)) return "T15 D20"
+ if (require(target, dartsLeft, 84, 2)) return "T20 D12"
+ if (require(target, dartsLeft, 83, 2)) return "T17 D16"
+ if (require(target, dartsLeft, 82, 2)) return "T14 D20"
+ if (require(target, dartsLeft, 81, 2)) return "T19 D12"
+ if (require(target, dartsLeft, 80, 2)) return "T20 D10"
+ if (require(target, dartsLeft, 79, 2)) return "T13 D20"
+ if (require(target, dartsLeft, 78, 2)) return "T18 D12"
+ if (require(target, dartsLeft, 77, 2)) return "T19 D10"
+ if (require(target, dartsLeft, 76, 2)) return "T20 D8"
+ if (require(target, dartsLeft, 75, 2)) return "T17 D12"
+ if (require(target, dartsLeft, 74, 2)) return "T18 D10"
+ if (require(target, dartsLeft, 73, 2)) return "T19 D8"
+ if (require(target, dartsLeft, 72, 2)) return "T12 D18"
+ if (require(target, dartsLeft, 71, 2)) return "T17 D10"
+ if (require(target, dartsLeft, 70, 2)) return "20 BULL"
+ if (require(target, dartsLeft, 70, 3)) return "T10 D20"
+ if (require(target, dartsLeft, 69, 2)) return "T13 D15"
+ if (require(target, dartsLeft, 68, 2)) return "T20 D4"
+ if (require(target, dartsLeft, 67, 2)) return "T17 D8"
+ if (require(target, dartsLeft, 66, 2)) return "T10 D18"
+ if (require(target, dartsLeft, 65, 2)) return "S.BULL D20"
+ if (require(target, dartsLeft, 64, 2)) return "T16 D8"
+ if (require(target, dartsLeft, 63, 2)) return "T13 D12"
+ if (require(target, dartsLeft, 62, 2)) return "T10 D16"
+ if (require(target, dartsLeft, 61, 2)) return "S.BULL D18"
+ if (require(target, dartsLeft, 60, 2)) return "20 D20"
+ if (require(target, dartsLeft, 59, 2)) return "19 D20"
+ if (require(target, dartsLeft, 58, 2)) return "18 D20"
+ if (require(target, dartsLeft, 57, 2)) return "17 D20"
+ if (require(target, dartsLeft, 56, 2)) return "T16 D4"
+ if (require(target, dartsLeft, 55, 2)) return "15 D20"
+ if (require(target, dartsLeft, 54, 2)) return "14 D20"
+ if (require(target, dartsLeft, 53, 2)) return "13 D20"
+ if (require(target, dartsLeft, 52, 2)) return "T12 D8"
+ if (require(target, dartsLeft, 51, 2)) return "11 D20"
+ if (require(target, dartsLeft, 50, 2)) return "10 D20"
+ if (require(target, dartsLeft, 50, 1)) return "BULL" // Special case
+ if (require(target, dartsLeft, 49, 2)) return "9 D20"
+ if (require(target, dartsLeft, 48, 2)) return "16 D16"
+ if (require(target, dartsLeft, 47, 2)) return "15 D16"
+ if (require(target, dartsLeft, 46, 2)) return "6 D20"
+ if (require(target, dartsLeft, 45, 2)) return "13 D16"
+ if (require(target, dartsLeft, 44, 2)) return "12 D16"
+ if (require(target, dartsLeft, 43, 2)) return "11 D16"
+ if (require(target, dartsLeft, 42, 2)) return "10 D16"
+ if (require(target, dartsLeft, 41, 2)) return "9 D16"
+ if (require(target, dartsLeft, 40, 3)) return "8 D16"
+ if (require(target, dartsLeft, 40, 1)) return "D20"
+ if (require(target, dartsLeft, 39, 2)) return "7 D16"
+ if (require(target, dartsLeft, 38, 3)) return "6 D16"
+ if (require(target, dartsLeft, 38, 1)) return "D19"
+ if (require(target, dartsLeft, 37, 2)) return "5 D16"
+ if (require(target, dartsLeft, 36, 3)) return "4 D16"
+ if (require(target, dartsLeft, 36, 1)) return "D18"
+ if (require(target, dartsLeft, 35, 2)) return "3 D16"
+ if (require(target, dartsLeft, 34, 3)) return "2 D16"
+ if (require(target, dartsLeft, 34, 1)) return "D17"
+ if (require(target, dartsLeft, 33, 2)) return "1 D16"
+ if (require(target, dartsLeft, 32, 1)) return "D16"
+ if (require(target, dartsLeft, 31, 2)) return "15 D8"
+ if (require(target, dartsLeft, 30, 3)) return "14 D8"
+ if (require(target, dartsLeft, 30, 1)) return "D15"
+ if (require(target, dartsLeft, 29, 2)) return "13 D8"
+ if (require(target, dartsLeft, 28, 2)) return "12 D8"
+ if (require(target, dartsLeft, 28, 1)) return "D14"
+ if (require(target, dartsLeft, 27, 2)) return "19 D4"
+ if (require(target, dartsLeft, 26, 3)) return "18 D4"
+ if (require(target, dartsLeft, 26, 1)) return "D13"
+ if (require(target, dartsLeft, 25, 2)) return "17 D4"
+ if (require(target, dartsLeft, 24, 3)) return "16 D4"
+ if (require(target, dartsLeft, 24, 1)) return "D12"
+ if (require(target, dartsLeft, 23, 2)) return "7 D8"
+ if (require(target, dartsLeft, 22, 2)) return "6 D8"
+ if (require(target, dartsLeft, 22, 1)) return "D11"
+ if (require(target, dartsLeft, 21, 2)) return "5 D8"
+ if (require(target, dartsLeft, 20, 1)) return "D10"
+ if (require(target, dartsLeft, 19, 2)) return "11 D4"
+ if (require(target, dartsLeft, 18, 3)) return "2 D8"
+ if (require(target, dartsLeft, 18, 1)) return "D9"
+ if (require(target, dartsLeft, 17, 2)) return "9 D4"
+ if (require(target, dartsLeft, 16, 1)) return "D8"
+ if (require(target, dartsLeft, 15, 2)) return "7 D4"
+ if (require(target, dartsLeft, 14, 1)) return "D7"
+ if (require(target, dartsLeft, 13, 2)) return "5 D4"
+ if (require(target, dartsLeft, 12, 1)) return "D6"
+ if (require(target, dartsLeft, 11, 2)) return "3 D4"
+ if (require(target, dartsLeft, 10, 1)) return "D5"
+ if (require(target, dartsLeft, 9, 2)) return "1 D4"
+ if (require(target, dartsLeft, 8, 1)) return "D4"
+ if (require(target, dartsLeft, 7, 2)) return "3 D2"
+ if (require(target, dartsLeft, 6, 1)) return "D3"
+ if (require(target, dartsLeft, 5, 2)) return "1 D2"
+ if (require(target, dartsLeft, 4, 1)) return "D2"
+ if (require(target, dartsLeft, 3, 2)) return "1 D1"
+ if (require(target, dartsLeft, 2, 1)) return "D1"
+
+ // Okay, now we have some options -> so let's go
+// if (target == dartsLeft.total() && dartsLeft.last().isDouble()) return dartsLeft.asFinish()
+// if (dartsLeft == 0) return notPossible
+
+ // TODO: Try Doubles + BULL
+ // TODO: If fails, add 1 dart for all singles, triples
+ // TODO: Recurse;)
+
+ // All Doubles, + 1 BULL, All Singles, S.BULL, All Tripples
+ return notPossible
+ }
+
+ private fun require(score: Int, dartsLeft: Int, target: Int, darts: Int) =
+ score == target && dartsLeft >= darts
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/InputListener.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/InputListener.kt
index a11399b5..54e3ebb7 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/InputListener.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/InputListener.kt
@@ -7,6 +7,7 @@ import nl.entreco.domain.model.players.Player
* Created by Entreco on 19/11/2017.
*/
interface InputListener {
+ fun onUndo()
fun onDartThrown(turn: Turn, by: Player)
fun onTurnSubmitted(turn: Turn, by: Player)
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/SpecialEventListener.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/SpecialEventListener.kt
index 595f5904..ac9dcf8e 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/SpecialEventListener.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/SpecialEventListener.kt
@@ -1,26 +1,33 @@
package nl.entreco.domain.play.listeners
-import nl.entreco.domain.play.listeners.events.*
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
+import nl.entreco.domain.play.listeners.events.*
/**
* Created by Entreco on 05/12/2017.
*/
+@Suppress("UNCHECKED_CAST")
interface SpecialEventListener {
fun handle(event: T)
fun onSpecialEvent(next: Next, turn: Turn, by: Player, scores: Array) {
- handleOneEight(turn)
handleNoScore(turn)
handleBust(next)
handleThrown(turn)
+
+ if (playing501(scores)) {
+ handleNineDarter(turn, scores, next, by)
+ }
}
+ fun playing501(scores: Array) =
+ scores[0].settings.startScore == 501
+
private fun handleThrown(turn: Turn) {
try {
val event = ThrownEvent(turn.asFinish()) as T
@@ -47,13 +54,43 @@ interface SpecialEventListener {
}
}
- private fun handleOneEight(turn: Turn) {
- if (turn.total() == 180) {
- try {
- val event = OneEightyEvent() as T
- handle(event)
- } catch (ignore: ClassCastException) {
- }
+ private fun handleNineDarter(turn: Turn, scores: Array, next: Next, by: Player) {
+ try {
+ val canItBePossible = canItBePossible(turn, scores, next)
+ val event = NineDartEvent(canItBePossible, by) as T
+ handle(event)
+ } catch (ignore: ClassCastException) {
+ }
+ }
+
+ private fun canItBePossible(turn: Turn, scores: Array, next: Next) : Boolean{
+ val score = previousTeamIndex(next.teamIndex, scores).score
+ val pnd = isPossibleNineDarter(turn.total(), score)
+ return turn.dartsLeft() == 0 && pnd
+ }
+
+ private fun previousTeamIndex(index: Int, scores: Array): Score {
+ var previousIndex = index - 1
+ if (previousIndex < 0) {
+ previousIndex = scores.size - 1
+ }
+ return scores[previousIndex]
+ }
+
+ private fun isPossibleNineDarter(scored: Int, score: Int): Boolean {
+ return when {
+ scored == 180 && score == 321 -> true
+ scored == 177 && score == 324 -> true
+ scored == 171 && score == 330 -> true
+ scored == 167 && score == 334 -> true
+ scored == 180 && score == 150 -> true
+ scored == 180 && score == 141 -> true
+ scored == 180 && score == 144 -> true
+ scored == 177 && score == 147 -> true
+ scored == 177 && score == 144 -> true
+ scored == 171 && score == 150 -> true
+ scored == 167 && score == 167 -> true
+ else -> false
}
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/StatListener.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/StatListener.kt
new file mode 100644
index 00000000..5f1adea1
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/StatListener.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.listeners
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+interface StatListener {
+ fun onStatsChange(turnId: Long, metaId: Long)
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/events/NineDartEvent.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/events/NineDartEvent.kt
new file mode 100644
index 00000000..4b834725
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/events/NineDartEvent.kt
@@ -0,0 +1,14 @@
+package nl.entreco.domain.play.listeners.events
+
+import nl.entreco.domain.model.players.Player
+
+
+class NineDartEvent(private val possible: Boolean, private val by: Player) : SpecialEvent {
+ fun isPossible(): Boolean {
+ return possible
+ }
+
+ fun by(): Player {
+ return by
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/events/OneEightyEvent.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/events/OneEightyEvent.kt
deleted file mode 100644
index 9df0e59c..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/listeners/events/OneEightyEvent.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package nl.entreco.domain.play.listeners.events
-
-/**
- * Created by Entreco on 05/12/2017.
- */
-class OneEightyEvent : SpecialEvent
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/MarkGameAsFinishedRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/MarkGameAsFinishedRequest.kt
new file mode 100644
index 00000000..f15f5616
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/MarkGameAsFinishedRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.start
+
+/**
+ * Created by entreco on 09/01/2018.
+ */
+data class MarkGameAsFinishedRequest(val gameId: Long)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/MarkGameAsFinishedUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/MarkGameAsFinishedUsecase.kt
new file mode 100644
index 00000000..d51235ed
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/MarkGameAsFinishedUsecase.kt
@@ -0,0 +1,18 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.GameRepository
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 09/01/2018.
+ */
+class MarkGameAsFinishedUsecase @Inject constructor(private val gameRepository: GameRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
+ fun exec(request: MarkGameAsFinishedRequest) {
+ onBackground({
+ gameRepository.finish(request.gameId)
+ }, {})
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Request.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Request.kt
new file mode 100644
index 00000000..c562d8da
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Request.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.start
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class Play01Request(val gameId: Long, val teamIds: String, val startScore: Int, val startIndex: Int, val numLegs: Int, val numSets: Int)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Response.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Response.kt
new file mode 100644
index 00000000..fd8f7a56
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Response.kt
@@ -0,0 +1,32 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.settings.ScoreSettings
+import java.util.*
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class Play01Response(val game: Game, val settings: ScoreSettings, val teams: Array, val teamIds: String) {
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as Play01Response
+
+ if (game != other.game) return false
+ if (settings != other.settings) return false
+ if (!Arrays.equals(teams, other.teams)) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = game.hashCode()
+ result = 31 * result + settings.hashCode()
+ result = 31 * result + Arrays.hashCode(teams)
+ return result
+ }
+
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Usecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Usecase.kt
new file mode 100644
index 00000000..b49c6717
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/Play01Usecase.kt
@@ -0,0 +1,82 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.Logger
+import nl.entreco.domain.model.TurnMeta
+import nl.entreco.domain.play.stats.*
+import nl.entreco.domain.settings.ScoreSettings
+import javax.inject.Inject
+
+/**
+ * Created by Entreco on 17/12/2017.
+ */
+class Play01Usecase @Inject constructor(private val retrieveGameUsecase: RetrieveGameUsecase,
+ private val retrieveTurnsUsecase: RetrieveTurnsUsecase,
+ private val retrieveTeamsUsecase: RetrieveTeamsUsecase,
+ private val storeTurnUsecase: StoreTurnUsecase,
+ private val storeMetaUsecase: StoreMetaUsecase,
+ private val undoTurnUsecase: UndoTurnUsecase,
+ private val markGameAsFinishedUsecase: MarkGameAsFinishedUsecase,
+ private val logger: Logger) {
+
+ fun loadGameAndStart(req: Play01Request, done: (Play01Response) -> Unit, fail: (Throwable) -> Unit) {
+ retrieveTeams(req, done, fail)
+ }
+
+ fun storeTurnAndMeta(req: StoreTurnRequest, turnMeta: TurnMeta, done: (Long, Long) -> Unit) {
+ storeTurnUsecase.exec(req,
+ onStoreTurnSuccess(req.gameId, turnMeta, done),
+ onFailed("Storing Turn failed ${req.turn}"))
+ }
+
+ fun undoLastTurn(req: UndoTurnRequest, done: (UndoTurnResponse) -> Unit, fail: (Throwable) -> Unit) {
+ undoTurnUsecase.exec(req, done , fail)
+ }
+
+ fun markGameAsFinished(finishRequest: MarkGameAsFinishedRequest) {
+ markGameAsFinishedUsecase.exec(finishRequest)
+ }
+
+ private fun onStoreTurnSuccess(gameId: Long, turnMeta: TurnMeta, done: (Long, Long) -> Unit) = { response: StoreTurnResponse ->
+ val metaRequest = StoreMetaRequest(response.turnId, gameId, response.turn, turnMeta)
+ storeMetaUsecase.exec(metaRequest, done, onFailed("Storing Stat failed $turnMeta"))
+ }
+
+ private fun onFailed(msg: String) = { err: Throwable ->
+ logger.w("$msg (${err.localizedMessage})")
+ }
+
+ private fun retrieveTeams(req: Play01Request, done: (Play01Response) -> Unit, fail: (Throwable) -> Unit) {
+ retrieveTeamsUsecase.exec(RetrieveTeamsRequest(req.teamIds),
+ { response -> retrieveGame(req, RetrieveGameRequest(req.gameId), response, done, fail) },
+ { err -> fail(err) }
+ )
+ }
+
+ private fun retrieveGame(playRequest: Play01Request, gameRequest: RetrieveGameRequest, teamResponse: RetrieveTeamsResponse, done: (Play01Response) -> Unit, fail: (Throwable) -> Unit) {
+ retrieveGameUsecase.start(gameRequest,
+ { response -> retrieveTurns(playRequest, response, teamResponse, done, fail) },
+ { err -> fail(err) }
+ )
+ }
+
+ private fun retrieveTurns(playRequest: Play01Request, gameResponse: RetrieveGameResponse, teamResponse: RetrieveTeamsResponse, done: (Play01Response) -> Unit, fail: (Throwable) -> Unit) {
+ retrieveTurnsUsecase.exec(RetrieveTurnsRequest(gameResponse.game.id),
+ { response ->
+ gameResponse.game.start(playRequest.startIndex, teamResponse.teams)
+
+ /**
+ * TODO: This 'prepares' the game for resuming.
+ * It makes sure all Scores are correctly applied,
+ * but also causes Play01ViewModel to have to ask Game
+ * for properties related to Stats only
+ * PRO -> Ensures an up-to-date game is ready to be resumed
+ * CON -> Game is responsible for tracking Stats - related - stuff
+ */
+ response.turns.forEach { gameResponse.game.handle(it.second) }
+ /** END OF TO DO */
+
+ val scoreSettings = ScoreSettings(playRequest.startScore, playRequest.numLegs, playRequest.numSets, playRequest.startIndex)
+ done.invoke(Play01Response(gameResponse.game, scoreSettings, teamResponse.teams, playRequest.teamIds))
+ }, { err -> fail(err) })
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameRequest.kt
new file mode 100644
index 00000000..8583fb5c
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.start
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class RetrieveGameRequest(val gameId: Long)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameResponse.kt
new file mode 100644
index 00000000..d35f0442
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.model.Game
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class RetrieveGameResponse(val game: Game)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveGameUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameUsecase.kt
similarity index 54%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveGameUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameUsecase.kt
index 80b4b821..4404bb07 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveGameUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveGameUsecase.kt
@@ -1,9 +1,8 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.start
-import nl.entreco.domain.executors.Background
import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.model.Game
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
import nl.entreco.domain.repository.GameRepository
import javax.inject.Inject
@@ -14,10 +13,10 @@ class RetrieveGameUsecase @Inject constructor(private val gameRepository: GameRe
bg: Background,
fg: Foreground) : BaseUsecase(bg, fg) {
- fun start(gameId: Long, ok: (Game) -> Unit, err: (Throwable) -> Unit) {
+ fun start(request: RetrieveGameRequest, ok: (RetrieveGameResponse) -> Unit, err: (Throwable) -> Unit) {
onBackground({
- val game = gameRepository.fetchBy(gameId)
- onUi({ ok(game) })
+ val game = gameRepository.fetchBy(request.gameId)
+ onUi({ ok(RetrieveGameResponse(game)) })
}, err)
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsRequest.kt
new file mode 100644
index 00000000..60094c45
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.start
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class RetrieveTeamsRequest(val teamIdsString: String)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsResponse.kt
new file mode 100644
index 00000000..5d6072be
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsResponse.kt
@@ -0,0 +1,24 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.model.players.Team
+import java.util.*
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class RetrieveTeamsResponse(val teams: Array) {
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (javaClass != other?.javaClass) return false
+
+ other as RetrieveTeamsResponse
+
+ if (!Arrays.equals(teams, other.teams)) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ return Arrays.hashCode(teams)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveTeamsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsUsecase.kt
similarity index 72%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveTeamsUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsUsecase.kt
index 114ad941..0694f5a3 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveTeamsUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTeamsUsecase.kt
@@ -1,11 +1,10 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.start
-import nl.entreco.domain.executors.Background
import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Foreground
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.repository.TeamIdsString
import nl.entreco.domain.repository.PlayerRepository
import javax.inject.Inject
@@ -14,10 +13,10 @@ import javax.inject.Inject
*/
class RetrieveTeamsUsecase @Inject constructor(private val playerRepository: PlayerRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg){
- fun exec(teamIds: TeamIdsString, done: (Array) -> Unit, fail: (Throwable) -> Unit) {
+ fun exec(request: RetrieveTeamsRequest, done: (RetrieveTeamsResponse) -> Unit, fail: (Throwable) -> Unit) {
onBackground({
- val teams = retrieveTeams(teamIds.toString())
- onUi { done(teams) }
+ val teams = retrieveTeams(request.teamIdsString)
+ onUi { done(RetrieveTeamsResponse(teams)) }
}, fail)
}
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsRequest.kt
new file mode 100644
index 00000000..ebe77739
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.start
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class RetrieveTurnsRequest(val gameId: Long)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsResponse.kt
new file mode 100644
index 00000000..4b5b9704
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.model.Turn
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class RetrieveTurnsResponse(val turns: List>)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsUsecase.kt
new file mode 100644
index 00000000..c7f8f6c4
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/start/RetrieveTurnsUsecase.kt
@@ -0,0 +1,19 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.TurnRepository
+import javax.inject.Inject
+
+/**
+ * Created by Entreco on 23/12/2017.
+ */
+class RetrieveTurnsUsecase @Inject constructor(private val turnRepository: TurnRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
+ fun exec(request: RetrieveTurnsRequest, done: (RetrieveTurnsResponse) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+ val turns = turnRepository.fetchTurnsForGame(request.gameId)
+ onUi { done(RetrieveTurnsResponse(turns)) }
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatRequest.kt
new file mode 100644
index 00000000..d5cad924
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.stats
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+data class FetchGameStatRequest(val turnId: Long, val metaId: Long)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatResponse.kt
new file mode 100644
index 00000000..cf149c9e
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.model.Stat
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+data class FetchGameStatResponse(val stat: Stat)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatUsecase.kt
new file mode 100644
index 00000000..c1298801
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatUsecase.kt
@@ -0,0 +1,24 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.StatRepository
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+class FetchGameStatUsecase @Inject constructor(
+ private val statRepository: StatRepository,
+ bg: Background,
+ fg: Foreground) : BaseUsecase(bg, fg) {
+
+ fun exec(req: FetchGameStatRequest, done: (FetchGameStatResponse) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+ val stat = statRepository.fetchStat(req.turnId, req.metaId)
+ onUi { done(FetchGameStatResponse(stat)) }
+
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsRequest.kt
new file mode 100644
index 00000000..f6a95381
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.stats
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+data class FetchGameStatsRequest(val gameId: Long, val teamIds: String)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsResponse.kt
new file mode 100644
index 00000000..d119ae41
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.model.Stat
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+data class FetchGameStatsResponse(val gameId: Long, val stats: Map)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsUsecase.kt
new file mode 100644
index 00000000..1c3a4259
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/FetchGameStatsUsecase.kt
@@ -0,0 +1,24 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.StatRepository
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+class FetchGameStatsUsecase @Inject constructor(
+ private val statRepository: StatRepository,
+ bg: Background,
+ fg: Foreground) : BaseUsecase(bg, fg) {
+
+ fun exec(req: FetchGameStatsRequest, done: (FetchGameStatsResponse) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+ val stats = statRepository.fetchAllForGame(req.gameId)
+ onUi { done(FetchGameStatsResponse(req.gameId, stats)) }
+
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreMetaRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreMetaRequest.kt
new file mode 100644
index 00000000..93776ac2
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreMetaRequest.kt
@@ -0,0 +1,9 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.TurnMeta
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+data class StoreMetaRequest(val turnId: Long, val gameId: Long, val turn: Turn, val turnMeta: TurnMeta)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreMetaUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreMetaUsecase.kt
new file mode 100644
index 00000000..a73f8cea
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreMetaUsecase.kt
@@ -0,0 +1,26 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.play.ScoreEstimator
+import nl.entreco.domain.repository.MetaRepository
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+class StoreMetaUsecase @Inject constructor(
+ private val metaRepository: MetaRepository,
+ private val scoreEstimator: ScoreEstimator,
+ bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
+
+ fun exec(req: StoreMetaRequest, done: (Long, Long) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+
+ val atDouble = scoreEstimator.atDouble(req.turn, req.turnMeta.score.score)
+ val metaId = metaRepository.create(req.turnId, req.gameId, req.turnMeta, atDouble)
+ onUi { done(req.turnId, metaId) }
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnRequest.kt
new file mode 100644
index 00000000..eeb112fc
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnRequest.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.model.Turn
+
+/**
+ * Created by Entreco on 23/12/2017.
+ */
+data class StoreTurnRequest(val playerId: Long, val gameId: Long, val turn: Turn)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnResponse.kt
new file mode 100644
index 00000000..aa92006a
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.model.Turn
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+data class StoreTurnResponse(val turnId: Long, val turn: Turn)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnUsecase.kt
new file mode 100644
index 00000000..0208c2f6
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/StoreTurnUsecase.kt
@@ -0,0 +1,20 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.TurnRepository
+import javax.inject.Inject
+
+/**
+ * Created by Entreco on 23/12/2017.
+ */
+class StoreTurnUsecase @Inject constructor(private val turnRepository: TurnRepository,
+ bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
+ fun exec(req: StoreTurnRequest, done: (StoreTurnResponse) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+ val turnId = turnRepository.store(req.gameId, req.playerId, req.turn)
+ onUi { done(StoreTurnResponse(turnId, req.turn)) }
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnRequest.kt
new file mode 100644
index 00000000..b0e7afb4
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.stats
+
+/**
+ * Created by entreco on 25/01/2018.
+ */
+data class UndoTurnRequest(val gameId: Long)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnResponse.kt
new file mode 100644
index 00000000..92c5fe22
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnResponse.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.play.stats
+
+/**
+ * Created by entreco on 25/01/2018.
+ */
+data class UndoTurnResponse(val deletedTurns: Int, val deletedMetas: Int)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnUsecase.kt
new file mode 100644
index 00000000..f7de4f87
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/stats/UndoTurnUsecase.kt
@@ -0,0 +1,31 @@
+package nl.entreco.domain.play.stats
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.GameRepository
+import nl.entreco.domain.repository.MetaRepository
+import nl.entreco.domain.repository.TurnRepository
+import javax.inject.Inject
+
+/**
+ * Created by entreco on 25/01/2018.
+ */
+class UndoTurnUsecase @Inject constructor(private val turnRepository: TurnRepository,
+ private val metaRepository: MetaRepository,
+ private val gameRepository: GameRepository,
+ bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
+
+ fun exec(req: UndoTurnRequest, done: (UndoTurnResponse) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+
+ /* !Important -> Make sure game does not hang in Finished state! */
+ gameRepository.undoFinish(req.gameId)
+
+ val turnsDeleted = turnRepository.undo(req.gameId)
+ val metasDeleted = metaRepository.undo(req.gameId)
+
+ onUi { done(UndoTurnResponse(turnsDeleted, metasDeleted)) }
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/GetFinishUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/GetFinishUsecase.kt
deleted file mode 100644
index 523f1b49..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/GetFinishUsecase.kt
+++ /dev/null
@@ -1,233 +0,0 @@
-package nl.entreco.domain.play.usecase
-
-import android.support.annotation.VisibleForTesting
-import android.support.annotation.WorkerThread
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
-import java.util.concurrent.Future
-import javax.inject.Inject
-
-/**
- * Created by Entreco on 24/11/2017.
- */
-class GetFinishUsecase @Inject constructor(private val bg: Background) {
-
- fun calculate(score: Score, turn: Turn, favDouble: Int, result: (String) -> Unit): Future<*>? {
- return bg.post(Runnable {
- val finish = calculateInBack(score.score, turn.copy(), favDouble)
- result(finish)
- })
- }
-
- private val impossible = arrayOf(169, 168, 166, 165, 163, 162, 159)
- val notPossible = ""
-
- @WorkerThread
- @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
- fun calculateInBack(score: Int, turn: Turn, favDouble: Int): String {
-
- // Calculate desired target
- val target = score - turn.total()
-
- // First, handle the obvious cases before we go into recursion ;)
- if (target > 170) return notPossible
- if (target <= 1) return notPossible
- if (impossible.contains(target)) return notPossible
-
- // Now, hardcode some values that do not need favourite Double, since
- // it can only be done in 1 way
- if (require(target, turn, 170, 3)) return "T20 T20 BULL"
- if (require(target, turn, 167, 3)) return "T20 T19 BULL"
- if (require(target, turn, 164, 3)) return "T20 T18 BULL"
- if (require(target, turn, 161, 3)) return "T20 T17 BULL"
- if (require(target, turn, 160, 3)) return "T20 T20 D20"
- if (require(target, turn, 158, 3)) return "T20 T20 D19"
- if (require(target, turn, 157, 3)) return "T20 T19 D20"
- if (require(target, turn, 156, 3)) return "T20 T20 D18"
- if (require(target, turn, 155, 3)) return "T20 T19 D19"
- if (require(target, turn, 154, 3)) return "T20 T18 D20"
- if (require(target, turn, 153, 3)) return "T20 T19 D18"
- if (require(target, turn, 152, 3)) return "T20 T20 D16"
- if (require(target, turn, 151, 3)) return "T20 T17 D20"
- if (require(target, turn, 150, 3)) return "T20 T18 D18"
- if (require(target, turn, 149, 3)) return "T20 T19 D16"
- if (require(target, turn, 148, 3)) return "T20 T16 D20"
- if (require(target, turn, 147, 3)) return "T19 T18 D18"
- if (require(target, turn, 146, 3)) return "T20 T18 D16"
- if (require(target, turn, 145, 3)) return "T20 T15 D20"
- if (require(target, turn, 144, 3)) return "T20 T20 D12"
- if (require(target, turn, 143, 3)) return "T20 T17 D16"
- if (require(target, turn, 142, 3)) return "T20 T14 D20"
- if (require(target, turn, 141, 3)) return "T20 T19 D12"
- if (require(target, turn, 140, 3)) return "T20 T16 D16"
- if (require(target, turn, 139, 3)) return "T19 T14 D20"
- if (require(target, turn, 138, 3)) return "T20 T18 D12"
- if (require(target, turn, 137, 3)) return "T19 T16 D16"
- if (require(target, turn, 136, 3)) return "T20 T20 D8"
- if (require(target, turn, 135, 3)) return "T20 T17 D12"
- if (require(target, turn, 134, 3)) return "T20 T14 D16"
- if (require(target, turn, 133, 3)) return "T20 T19 D8"
- if (require(target, turn, 132, 3)) return "T20 T16 D12"
- if (require(target, turn, 131, 3)) return "T20 T13 D16"
- if (require(target, turn, 130, 3)) return "T20 20 BULL"
- if (require(target, turn, 129, 3)) return "T19 T16 D12"
- if (require(target, turn, 128, 3)) return "T18 T14 D16"
- if (require(target, turn, 127, 3)) return "T20 T17 D8"
- if (require(target, turn, 126, 3)) return "T19 T19 D6"
- if (require(target, turn, 125, 3)) return "S.BULL T20 D20"
- if (require(target, turn, 124, 3)) return "T20 T16 D8"
- if (require(target, turn, 123, 3)) return "T19 T16 D9"
- if (require(target, turn, 122, 3)) return "T18 T20 D4"
- if (require(target, turn, 121, 3)) return "T17 T10 D20"
- if (require(target, turn, 120, 3)) return "T20 20 D20"
- if (require(target, turn, 119, 3)) return "T19 T10 D16"
- if (require(target, turn, 118, 3)) return "T20 18 D20"
- if (require(target, turn, 117, 3)) return "T20 17 D20"
- if (require(target, turn, 116, 3)) return "T20 16 D20"
- if (require(target, turn, 115, 3)) return "T20 15 D20"
- if (require(target, turn, 114, 3)) return "T20 14 D20"
- if (require(target, turn, 113, 3)) return "T20 13 D20"
- if (require(target, turn, 112, 3)) return "T20 12 D20"
- if (require(target, turn, 111, 3)) return "T20 19 D16"
- if (require(target, turn, 110, 3)) return "T20 18 D16"
- if (require(target, turn, 110, 2)) return "T20 BULL"
- if (require(target, turn, 109, 3)) return "T19 20 D16"
- if (require(target, turn, 108, 3)) return "T20 16 D16"
- if (require(target, turn, 107, 3)) return "T19 18 D16"
- if (require(target, turn, 107, 2)) return "T19 BULL"
- if (require(target, turn, 106, 3)) return "T20 14 D16"
- if (require(target, turn, 105, 3)) return "T19 16 D16"
- if (require(target, turn, 104, 3)) return "T18 18 D16"
- if (require(target, turn, 104, 2)) return "T18 BULL"
- if (require(target, turn, 103, 3)) return "T20 3 D20"
- if (require(target, turn, 102, 3)) return "T20 10 D16"
- if (require(target, turn, 101, 3)) return "T20 1 D20"
- if (require(target, turn, 101, 2)) return "T17 BULL"
- if (require(target, turn, 100, 2)) return "T20 D20"
- if (require(target, turn, 99, 3)) return "T19 10 D16"
- if (require(target, turn, 98, 2)) return "T20 D19"
- if (require(target, turn, 97, 2)) return "T19 D20"
- if (require(target, turn, 96, 2)) return "T20 D18"
- if (require(target, turn, 95, 2)) return "T19 D19"
- if (require(target, turn, 94, 2)) return "T18 D20"
- if (require(target, turn, 93, 2)) return "T19 D18"
- if (require(target, turn, 92, 2)) return "T20 D16"
- if (require(target, turn, 91, 2)) return "T17 D20"
- if (require(target, turn, 90, 2)) return "T20 D15"
- if (require(target, turn, 89, 2)) return "T19 D16"
- if (require(target, turn, 88, 2)) return "T16 D20"
- if (require(target, turn, 87, 2)) return "T17 D18"
- if (require(target, turn, 86, 2)) return "T18 D16"
- if (require(target, turn, 85, 2)) return "T15 D20"
- if (require(target, turn, 84, 2)) return "T20 D12"
- if (require(target, turn, 83, 2)) return "T17 D16"
- if (require(target, turn, 82, 2)) return "T14 D20"
- if (require(target, turn, 81, 2)) return "T19 D12"
- if (require(target, turn, 80, 2)) return "T20 D10"
- if (require(target, turn, 79, 2)) return "T13 D20"
- if (require(target, turn, 78, 2)) return "T18 D12"
- if (require(target, turn, 77, 2)) return "T19 D10"
- if (require(target, turn, 76, 2)) return "T20 D8"
- if (require(target, turn, 75, 2)) return "T17 D12"
- if (require(target, turn, 74, 2)) return "T18 D10"
- if (require(target, turn, 73, 2)) return "T19 D8"
- if (require(target, turn, 72, 2)) return "T12 D18"
- if (require(target, turn, 71, 2)) return "T17 D10"
- if (require(target, turn, 70, 2)) return "20 BULL"
- if (require(target, turn, 70, 3)) return "T10 D20"
- if (require(target, turn, 69, 2)) return "T13 D15"
- if (require(target, turn, 68, 2)) return "T20 D4"
- if (require(target, turn, 67, 2)) return "T17 D8"
- if (require(target, turn, 66, 2)) return "T10 D18"
- if (require(target, turn, 65, 2)) return "S.BULL D20"
- if (require(target, turn, 64, 2)) return "T16 D8"
- if (require(target, turn, 63, 2)) return "T13 D12"
- if (require(target, turn, 62, 2)) return "T10 D16"
- if (require(target, turn, 61, 2)) return "S.BULL D18"
- if (require(target, turn, 60, 2)) return "20 D20"
- if (require(target, turn, 59, 2)) return "19 D20"
- if (require(target, turn, 58, 2)) return "18 D20"
- if (require(target, turn, 57, 2)) return "17 D20"
- if (require(target, turn, 56, 2)) return "T16 D4"
- if (require(target, turn, 55, 2)) return "15 D20"
- if (require(target, turn, 54, 2)) return "14 D20"
- if (require(target, turn, 53, 2)) return "13 D20"
- if (require(target, turn, 52, 2)) return "T12 D8"
- if (require(target, turn, 51, 2)) return "11 D20"
- if (require(target, turn, 50, 2)) return "10 D20"
- if (require(target, turn, 50, 1)) return "BULL" // Special case
- if (require(target, turn, 49, 2)) return "9 D20"
- if (require(target, turn, 48, 2)) return "16 D16"
- if (require(target, turn, 47, 2)) return "15 D16"
- if (require(target, turn, 46, 2)) return "6 D20"
- if (require(target, turn, 45, 2)) return "13 D16"
- if (require(target, turn, 44, 2)) return "12 D16"
- if (require(target, turn, 43, 2)) return "11 D16"
- if (require(target, turn, 42, 2)) return "10 D16"
- if (require(target, turn, 41, 2)) return "9 D16"
- if (require(target, turn, 40, 3)) return "8 D16"
- if (require(target, turn, 40, 1)) return "D20"
- if (require(target, turn, 39, 2)) return "7 D16"
- if (require(target, turn, 38, 3)) return "6 D16"
- if (require(target, turn, 38, 1)) return "D19"
- if (require(target, turn, 37, 2)) return "5 D16"
- if (require(target, turn, 36, 3)) return "4 D16"
- if (require(target, turn, 36, 1)) return "D18"
- if (require(target, turn, 35, 2)) return "3 D16"
- if (require(target, turn, 34, 3)) return "2 D16"
- if (require(target, turn, 34, 1)) return "D17"
- if (require(target, turn, 33, 2)) return "1 D16"
- if (require(target, turn, 32, 1)) return "D16"
- if (require(target, turn, 31, 2)) return "15 D8"
- if (require(target, turn, 30, 3)) return "14 D8"
- if (require(target, turn, 30, 1)) return "D15"
- if (require(target, turn, 29, 2)) return "13 D8"
- if (require(target, turn, 28, 2)) return "12 D8"
- if (require(target, turn, 28, 1)) return "D14"
- if (require(target, turn, 27, 2)) return "19 D4"
- if (require(target, turn, 26, 3)) return "18 D4"
- if (require(target, turn, 26, 1)) return "D13"
- if (require(target, turn, 25, 2)) return "17 D4"
- if (require(target, turn, 24, 3)) return "16 D4"
- if (require(target, turn, 24, 1)) return "D12"
- if (require(target, turn, 23, 2)) return "7 D8"
- if (require(target, turn, 22, 2)) return "6 D8"
- if (require(target, turn, 22, 1)) return "D11"
- if (require(target, turn, 21, 2)) return "5 D8"
- if (require(target, turn, 20, 1)) return "D10"
- if (require(target, turn, 19, 2)) return "11 D4"
- if (require(target, turn, 18, 3)) return "2 D8"
- if (require(target, turn, 18, 1)) return "D9"
- if (require(target, turn, 17, 2)) return "9 D4"
- if (require(target, turn, 16, 1)) return "D8"
- if (require(target, turn, 15, 2)) return "7 D4"
- if (require(target, turn, 14, 1)) return "D7"
- if (require(target, turn, 13, 2)) return "5 D4"
- if (require(target, turn, 12, 1)) return "D6"
- if (require(target, turn, 11, 2)) return "3 D4"
- if (require(target, turn, 10, 1)) return "D5"
- if (require(target, turn, 9, 2)) return "1 D4"
- if (require(target, turn, 8, 1)) return "D4"
- if (require(target, turn, 7, 2)) return "3 D2"
- if (require(target, turn, 6, 1)) return "D3"
- if (require(target, turn, 5, 2)) return "1 D2"
- if (require(target, turn, 4, 1)) return "D2"
- if (require(target, turn, 3, 2)) return "1 D1"
- if (require(target, turn, 2, 1)) return "D1"
-
- // Okay, now we have some options -> so let's go
- if (target == turn.total() && turn.last().isDouble()) return turn.asFinish()
- if (turn.dartsLeft() == 0) return notPossible
-
- // TODO: Try Doubles + BULL
- // TODO: If fails, add 1 dart for all singles, triples
- // TODO: Recurse;)
-
- // All Doubles, + 1 BULL, All Singles, S.BULL, All Tripples
- return notPossible
- }
-
- private fun require(score: Int, turn: Turn, target: Int, darts: Int) =
- score == target && turn.dartsLeft() >= darts
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/Play01Usecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/Play01Usecase.kt
deleted file mode 100644
index 0ba600f1..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/Play01Usecase.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package nl.entreco.domain.play.usecase
-
-import nl.entreco.domain.model.Game
-import nl.entreco.domain.model.Turn
-import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.StoreTurnRequest
-import javax.inject.Inject
-
-/**
- * Created by Entreco on 17/12/2017.
- */
-class Play01Usecase @Inject constructor(private val retrieveGameUsecase: RetrieveGameUsecase,
- private val retrieveTurnsUsecase: RetrieveTurnsUsecase,
- private val retrieveTeamsUsecase: RetrieveTeamsUsecase,
- private val storeTurnUsecase: StoreTurnUsecase) {
-
- fun loadGameAndStart(req: RetrieveGameRequest, done: (Game, Array) -> Unit, fail: (Throwable) -> Unit) {
- retrieveTeams(req, done, fail)
- }
-
- fun storeTurn(req: StoreTurnRequest){
- storeTurnUsecase.exec(req)
- }
-
- private fun retrieveTeams(req: RetrieveGameRequest, done: (Game, Array) -> Unit, fail: (Throwable) -> Unit) {
- retrieveTeamsUsecase.exec(req.teamIds,
- { teams -> retrieveGame(req.gameId, req.create.startIndex, teams, done, fail) },
- { err -> fail(err) }
- )
- }
-
- private fun retrieveGame(gameId: Long, startIndex: Int, teams: Array, done: (Game, Array) -> Unit, fail: (Throwable) -> Unit) {
- retrieveGameUsecase.start(gameId,
- { game -> retrieveTurns(game, startIndex, teams, done, fail) },
- { err -> fail(err) }
- )
- }
-
- private fun retrieveTurns(game: Game, startIndex: Int, teams: Array, done: (Game, Array) -> Unit, fail: (Throwable) -> Unit) {
- retrieveTurnsUsecase.exec(game.id,
- { turns ->
- game.start(startIndex, teams)
- turns.forEach { game.handle(it) }
- done.invoke(game, teams)
- }, { err -> fail(err) })
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveTurnsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveTurnsUsecase.kt
deleted file mode 100644
index 4b2231e0..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/RetrieveTurnsUsecase.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package nl.entreco.domain.play.usecase
-
-import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.model.Turn
-import nl.entreco.domain.repository.TurnRepository
-import javax.inject.Inject
-
-/**
- * Created by Entreco on 23/12/2017.
- */
-class RetrieveTurnsUsecase @Inject constructor(private val turnRepository: TurnRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
- fun exec(gameId: Long, done: (Array) -> Unit, fail: (Throwable) -> Unit) {
- onBackground({
- val turns = turnRepository.fetchTurnsForGame(gameId)
- onUi { done(turns.toTypedArray()) }
- }, fail)
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/StoreTurnUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/StoreTurnUsecase.kt
deleted file mode 100644
index 45506bc4..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/play/usecase/StoreTurnUsecase.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package nl.entreco.domain.play.usecase
-
-import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.repository.StoreTurnRequest
-import nl.entreco.domain.repository.TurnRepository
-import javax.inject.Inject
-
-/**
- * Created by Entreco on 23/12/2017.
- */
-class StoreTurnUsecase @Inject constructor(private val turnRepository: TurnRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
- fun exec(req: StoreTurnRequest) {
- onBackground(
- { turnRepository.store(req.gameId, req.turn) },
- {})
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/CreateGameRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/CreateGameRequest.kt
deleted file mode 100644
index f61f9ab0..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/CreateGameRequest.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package nl.entreco.domain.repository
-
-import android.os.Parcel
-import android.os.Parcelable
-
-/**
- * Created by Entreco on 12/12/2017.
- */
-data class CreateGameRequest(val startScore: Int, val startIndex: Int, val numLegs: Int, val numSets: Int) : Parcelable {
- constructor(parcel: Parcel) : this(
- parcel.readInt(),
- parcel.readInt(),
- parcel.readInt(),
- parcel.readInt())
-
- override fun writeToParcel(parcel: Parcel, flags: Int) {
- parcel.writeInt(startScore)
- parcel.writeInt(startIndex)
- parcel.writeInt(numLegs)
- parcel.writeInt(numSets)
- }
-
- override fun describeContents(): Int {
- return 0
- }
-
- companion object CREATOR : Parcelable.Creator {
- override fun createFromParcel(parcel: Parcel): CreateGameRequest {
- return CreateGameRequest(parcel)
- }
-
- override fun newArray(size: Int): Array {
- return arrayOfNulls(size)
- }
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/GameRepository.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/GameRepository.kt
index 691a4103..6a81d0df 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/GameRepository.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/GameRepository.kt
@@ -18,6 +18,12 @@ interface GameRepository {
numLegs: Int,
numSets: Int): Long
+ @WorkerThread
+ fun finish(id: Long)
+
+ @WorkerThread
+ fun undoFinish(id: Long)
+
@Throws
@WorkerThread
fun fetchBy(id: Long): Game
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/MetaRepository.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/MetaRepository.kt
new file mode 100644
index 00000000..abcbc4c7
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/MetaRepository.kt
@@ -0,0 +1,16 @@
+package nl.entreco.domain.repository
+
+import android.support.annotation.WorkerThread
+import nl.entreco.domain.model.TurnMeta
+
+/**
+ * Created by entreco on 10/01/2018.
+ */
+interface MetaRepository {
+ @Throws
+ @WorkerThread
+ fun create(turnId: Long, gameId: Long, meta: TurnMeta, atDouble: Int): Long
+
+ @WorkerThread
+ fun undo(gameId: Long): Int
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/PreferenceRepository.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/PreferenceRepository.kt
index fd14630f..bc1075cc 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/PreferenceRepository.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/PreferenceRepository.kt
@@ -1,7 +1,7 @@
package nl.entreco.domain.repository
-import nl.entreco.domain.setup.usecase.FetchSettingsResponse
-import nl.entreco.domain.setup.usecase.StoreSettingsRequest
+import nl.entreco.domain.setup.settings.FetchSettingsResponse
+import nl.entreco.domain.setup.settings.StoreSettingsRequest
/**
* Created by entreco on 04/01/2018.
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/RetrieveGameRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/RetrieveGameRequest.kt
deleted file mode 100644
index 7d588355..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/RetrieveGameRequest.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package nl.entreco.domain.repository
-
-/**
- * Created by Entreco on 17/12/2017.
- */
-data class RetrieveGameRequest(val gameId: Long, val teamIds: TeamIdsString, val create: CreateGameRequest)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/StatRepository.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/StatRepository.kt
new file mode 100644
index 00000000..9340b455
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/StatRepository.kt
@@ -0,0 +1,16 @@
+package nl.entreco.domain.repository
+
+import android.support.annotation.WorkerThread
+import nl.entreco.domain.model.Stat
+
+/**
+ * Created by entreco on 16/01/2018.
+ */
+interface StatRepository {
+
+ @WorkerThread
+ fun fetchAllForGame(gameId: Long): Map
+
+ @WorkerThread
+ fun fetchStat(turnId: Long, metaId: Long): Stat
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/StoreTurnRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/StoreTurnRequest.kt
deleted file mode 100644
index 00b6ba04..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/StoreTurnRequest.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package nl.entreco.domain.repository
-
-import nl.entreco.domain.model.Turn
-
-/**
- * Created by Entreco on 23/12/2017.
- */
-data class StoreTurnRequest(val gameId: Long, val turn: Turn)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TeamIdsString.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TeamIdsString.kt
deleted file mode 100644
index 744fcde8..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TeamIdsString.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package nl.entreco.domain.repository
-
-/**
- * Created by Entreco on 17/12/2017.
- */
-data class TeamIdsString(private val teamString: String) {
- override fun toString(): String {
- return teamString
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TurnRepository.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TurnRepository.kt
index 32e95f0f..f52a46b3 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TurnRepository.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/repository/TurnRepository.kt
@@ -9,8 +9,11 @@ import nl.entreco.domain.model.Turn
interface TurnRepository {
@WorkerThread
- fun fetchTurnsForGame(gameId: Long): List
+ fun fetchTurnsForGame(gameId: Long): List>
@WorkerThread
- fun store(gameId: Long, turn: Turn)
+ fun store(gameId: Long, playerId: Long, turn: Turn): Long
+
+ @WorkerThread
+ fun undo(gameId: Long): Int
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameRequest.kt
new file mode 100644
index 00000000..057f0639
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameRequest.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.setup.game
+
+/**
+ * Created by Entreco on 12/12/2017.
+ */
+data class CreateGameRequest(val startScore: Int, val startIndex: Int, val numLegs: Int, val numSets: Int)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameResponse.kt
new file mode 100644
index 00000000..c72f9795
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameResponse.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.setup.game
+
+/**
+ * Created by Entreco on 17/12/2017.
+ */
+data class CreateGameResponse(val gameId: Long, val teamIds: String, val startScore: Int, val startIndex: Int, val numLegs: Int, val numSets: Int)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameUsecase.kt
new file mode 100644
index 00000000..64d7e6fc
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/game/CreateGameUsecase.kt
@@ -0,0 +1,21 @@
+package nl.entreco.domain.setup.game
+
+import nl.entreco.domain.BaseUsecase
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.repository.GameRepository
+import javax.inject.Inject
+
+/**
+ * Created by Entreco on 12/12/2017.
+ */
+class CreateGameUsecase @Inject constructor(private val gameRepository: GameRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
+
+ fun exec(request: CreateGameRequest, teamIdString: String, done: (CreateGameResponse) -> Unit, fail: (Throwable) -> Unit) {
+ onBackground({
+ val (score, index, legs, sets) = request
+ val id = gameRepository.create(teamIdString, score, index, legs, sets)
+ onUi { done(CreateGameResponse(id, teamIdString, score, index, legs, sets)) }
+ }, fail)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/CreatePlayerRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerRequest.kt
similarity index 72%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/CreatePlayerRequest.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerRequest.kt
index df1fad3f..6c08f3a3 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/CreatePlayerRequest.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerRequest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.players
/**
* Created by Entreco on 02/01/2018.
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerResponse.kt
new file mode 100644
index 00000000..257d0579
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.setup.players
+
+import nl.entreco.domain.model.players.Player
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class CreatePlayerResponse(val player: Player)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/CreatePlayerUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerUsecase.kt
similarity index 69%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/CreatePlayerUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerUsecase.kt
index 0dcf4884..edd8d47d 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/CreatePlayerUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerUsecase.kt
@@ -1,8 +1,8 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.players
import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.PlayerPrefs
import nl.entreco.domain.repository.PlayerRepository
@@ -12,11 +12,11 @@ import javax.inject.Inject
* Created by Entreco on 02/01/2018.
*/
class CreatePlayerUsecase @Inject constructor(private var playerRepository: PlayerRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
- fun exec(req: CreatePlayerRequest, done: (Player) -> Unit, fail: (Throwable) -> Unit) {
+ fun exec(req: CreatePlayerRequest, done: (CreatePlayerResponse) -> Unit, fail: (Throwable) -> Unit) {
onBackground({
val validLowercaseName = getValidLowerCaseName(req.name)
val playerId = playerRepository.create(validLowercaseName, req.double)
- onUi { done(Player(validLowercaseName, playerId, PlayerPrefs(req.double))) }
+ onUi { done(CreatePlayerResponse(Player(validLowercaseName, playerId, PlayerPrefs(req.double)))) }
}, fail)
}
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/FetchExistingPlayersResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/FetchExistingPlayersResponse.kt
new file mode 100644
index 00000000..113a69e6
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/FetchExistingPlayersResponse.kt
@@ -0,0 +1,8 @@
+package nl.entreco.domain.setup.players
+
+import nl.entreco.domain.model.players.Player
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+data class FetchExistingPlayersResponse(val players: List)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchExistingPlayersUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/FetchExistingPlayersUsecase.kt
similarity index 58%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchExistingPlayersUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/FetchExistingPlayersUsecase.kt
index f0c2a372..19af5bad 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchExistingPlayersUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/FetchExistingPlayersUsecase.kt
@@ -1,9 +1,8 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.players
import nl.entreco.domain.BaseUsecase
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
import nl.entreco.domain.repository.PlayerRepository
import javax.inject.Inject
@@ -11,10 +10,10 @@ import javax.inject.Inject
* Created by Entreco on 02/01/2018.
*/
class FetchExistingPlayersUsecase @Inject constructor(private var playerRepository: PlayerRepository, bg: Background, fg: Foreground) : BaseUsecase(bg, fg) {
- fun exec(done: (List) -> Unit, fail: (Throwable) -> Unit) {
+ fun exec(done: (FetchExistingPlayersResponse) -> Unit, fail: (Throwable) -> Unit) {
onBackground({
val players = playerRepository.fetchAll()
- onUi({ done(players) })
+ onUi({ done(FetchExistingPlayersResponse(players)) })
}, fail)
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/InvalidPlayerNameException.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/InvalidPlayerNameException.kt
new file mode 100644
index 00000000..98bfaba7
--- /dev/null
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/players/InvalidPlayerNameException.kt
@@ -0,0 +1,6 @@
+package nl.entreco.domain.setup.players
+
+/**
+ * Created by entreco on 05/01/2018.
+ */
+class InvalidPlayerNameException(msg: String) : Throwable(msg)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchPreferredSettingsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/FetchPreferredSettingsUsecase.kt
similarity index 91%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchPreferredSettingsUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/FetchPreferredSettingsUsecase.kt
index 79d1ffb8..7498c0c3 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchPreferredSettingsUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/FetchPreferredSettingsUsecase.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
import nl.entreco.domain.repository.PreferenceRepository
import javax.inject.Inject
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchSettingsResponse.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/FetchSettingsResponse.kt
similarity index 93%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchSettingsResponse.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/FetchSettingsResponse.kt
index e916b0a9..cf82d469 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/FetchSettingsResponse.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/FetchSettingsResponse.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
/**
* Created by entreco on 04/01/2018.
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/StorePreferredSettingsUsecase.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/StorePreferredSettingsUsecase.kt
similarity index 88%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/StorePreferredSettingsUsecase.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/StorePreferredSettingsUsecase.kt
index 16093d23..c5c28ca7 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/StorePreferredSettingsUsecase.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/StorePreferredSettingsUsecase.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
import nl.entreco.domain.repository.PreferenceRepository
import javax.inject.Inject
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/StoreSettingsRequest.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/StoreSettingsRequest.kt
similarity index 57%
rename from android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/StoreSettingsRequest.kt
rename to android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/StoreSettingsRequest.kt
index 6331ceb2..435a240b 100644
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/StoreSettingsRequest.kt
+++ b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/settings/StoreSettingsRequest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
/**
* Created by entreco on 04/01/2018.
diff --git a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/InvalidPlayerNameException.kt b/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/InvalidPlayerNameException.kt
deleted file mode 100644
index 5d2750fe..00000000
--- a/android/DartsScorecard/domain/src/main/java/nl/entreco/domain/setup/usecase/InvalidPlayerNameException.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package nl.entreco.domain.setup.usecase
-
-/**
- * Created by entreco on 05/01/2018.
- */
-class InvalidPlayerNameException(msg: String) : Throwable(msg)
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/TestProvider.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/TestProvider.kt
index 4e440d81..f80a5736 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/TestProvider.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/TestProvider.kt
@@ -2,8 +2,8 @@ package nl.entreco.domain
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.State
+import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
import nl.entreco.domain.play.Arbiter
import nl.entreco.domain.play.TurnHandler
@@ -40,6 +40,14 @@ class TestProvider {
return teams
}
+ fun player1(): Player {
+ return player1
+ }
+
+ fun player2(): Player {
+ return player2
+ }
+
fun team1(): Team {
return team1
}
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/BgExecutorTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/BgExecutorTest.kt
similarity index 94%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/BgExecutorTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/BgExecutorTest.kt
index 26dbf6e4..26e12864 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/BgExecutorTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/BgExecutorTest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
import com.nhaarman.mockito_kotlin.verify
import org.junit.Before
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/FgExecutorTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/FgExecutorTest.kt
similarity index 93%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/FgExecutorTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/FgExecutorTest.kt
index 9b0919da..90408d7a 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/FgExecutorTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/FgExecutorTest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
import android.os.Handler
import com.nhaarman.mockito_kotlin.verify
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/TestBackground.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/TestBackground.kt
similarity index 86%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/TestBackground.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/TestBackground.kt
index f920fcdc..7e4f6832 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/TestBackground.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/TestBackground.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
import java.util.concurrent.Future
import java.util.concurrent.FutureTask
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/TestForeground.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/TestForeground.kt
similarity index 77%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/TestForeground.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/TestForeground.kt
index 042dcec1..366ffe7f 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/executors/TestForeground.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/common/executors/TestForeground.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.executors
+package nl.entreco.domain.common.executors
/**
* Created by Entreco on 12/12/2017.
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/TeamNamesStringTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsRequestTest.kt
similarity index 53%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/TeamNamesStringTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsRequestTest.kt
index 37ed25ce..2822d880 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/TeamNamesStringTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsRequestTest.kt
@@ -1,63 +1,68 @@
package nl.entreco.domain.launch
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertNotNull
+import org.junit.Assert
import org.junit.Test
/**
- * Created by Entreco on 16/12/2017.
+ * Created by entreco on 06/01/2018.
*/
-class TeamNamesStringTest {
-
+class ExtractTeamsRequestTest {
@Test(expected = IllegalStateException::class)
fun `invalid team strings, empty`() {
- TeamNamesString("")
+ ExtractTeamsRequest("")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, '|'`() {
- TeamNamesString("|")
+ ExtractTeamsRequest("|")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, '1,2|'`() {
- TeamNamesString("1,2|")
+ ExtractTeamsRequest("1,2|")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, '|1'`() {
- TeamNamesString("|1")
+ ExtractTeamsRequest("|1")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, ',|'`() {
- TeamNamesString(",|")
+ ExtractTeamsRequest(",|")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, '|,'`() {
- TeamNamesString("|,")
+ ExtractTeamsRequest("|,")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, '||'`() {
- TeamNamesString("||")
+ ExtractTeamsRequest("||")
}
+
@Test(expected = IllegalStateException::class)
fun `invalid team strings, ',,'`() {
- TeamNamesString(",,")
+ ExtractTeamsRequest(",,")
}
@Test
fun `valid team strings`() {
- assertNotNull(TeamNamesString("player1"))
- assertNotNull(TeamNamesString("player1,player2"))
+ Assert.assertNotNull(ExtractTeamsRequest("player1"))
+ Assert.assertNotNull(ExtractTeamsRequest("player1,player2"))
}
@Test
fun `should have correct number of players`() {
- assertEquals(3, TeamNamesString("1,2,3").toPlayerNames().size)
- assertEquals(3, TeamNamesString("1|2,3").toPlayerNames().size)
- assertEquals(3, TeamNamesString("1|2,3").toPlayerNames().size)
+ Assert.assertEquals(3, ExtractTeamsRequest("1,2,3").toPlayerNames().size)
+ Assert.assertEquals(3, ExtractTeamsRequest("1|2,3").toPlayerNames().size)
+ Assert.assertEquals(3, ExtractTeamsRequest("1|2,3").toPlayerNames().size)
}
@Test
fun `should print correct string`() {
- assertEquals("1,2,3", TeamNamesString("1,2,3").toString())
- assertEquals("1|2,3", TeamNamesString("1|2,3").toString())
+ Assert.assertEquals("1,2,3", ExtractTeamsRequest("1,2,3").toString())
+ Assert.assertEquals("1|2,3", ExtractTeamsRequest("1|2,3").toString())
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsResponseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsResponseTest.kt
new file mode 100644
index 00000000..10b470b6
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsResponseTest.kt
@@ -0,0 +1,14 @@
+package nl.entreco.domain.launch
+
+import org.junit.Assert
+import org.junit.Test
+
+/**
+ * Created by entreco on 06/01/2018.
+ */
+class ExtractTeamsResponseTest {
+ @Test
+ fun `it should return correct string representation`() {
+ Assert.assertEquals("1,2|3", ExtractTeamsResponse("1,2|3").teamNames)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/ExtractTeamsUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsUsecaseTest.kt
similarity index 80%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/ExtractTeamsUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsUsecaseTest.kt
index d6e7c06c..f9cb2918 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/ExtractTeamsUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/ExtractTeamsUsecaseTest.kt
@@ -1,13 +1,11 @@
-package nl.entreco.domain.launch.usecase
+package nl.entreco.domain.launch
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
-import nl.entreco.domain.launch.TeamNamesString
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.repository.PlayerRepository
-import nl.entreco.domain.repository.TeamIdsString
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
@@ -19,13 +17,13 @@ import org.mockito.MockitoAnnotations
class ExtractTeamsUsecaseTest {
@Mock private lateinit var mockPlayerRepository: PlayerRepository
- @Mock private lateinit var mockOk: (TeamIdsString) -> Unit
+ @Mock private lateinit var mockOk: (ExtractTeamsResponse) -> Unit
@Mock private lateinit var mockFail: (Throwable) -> Unit
private lateinit var subject: ExtractTeamsUsecase
private val bg = TestBackground()
private val fg = TestForeground()
- private lateinit var givenTeamNames: TeamNamesString
+ private lateinit var givenTeamNames: ExtractTeamsRequest
@Before
fun setUp() {
@@ -48,7 +46,7 @@ class ExtractTeamsUsecaseTest {
}
private fun givenTeams(teamString: String) {
- givenTeamNames = TeamNamesString(teamString)
+ givenTeamNames = ExtractTeamsRequest(teamString)
}
private fun whenStartingUsecase() {
@@ -67,7 +65,7 @@ class ExtractTeamsUsecaseTest {
}
private fun thenCallbackIsNotified(expected: String) {
- verify(mockOk).invoke(TeamIdsString(expected))
+ verify(mockOk).invoke(ExtractTeamsResponse(expected))
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/RetrieveLatestGameUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/RetrieveLatestGameUsecaseTest.kt
similarity index 64%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/RetrieveLatestGameUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/RetrieveLatestGameUsecaseTest.kt
index 2b6e15a6..c889f596 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/RetrieveLatestGameUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/RetrieveLatestGameUsecaseTest.kt
@@ -1,17 +1,14 @@
-package nl.entreco.domain.launch.usecase
+package nl.entreco.domain.launch
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
-import nl.entreco.domain.launch.FetchLatestGameResponse
-import nl.entreco.domain.repository.CreateGameRequest
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.repository.GameRepository
-import nl.entreco.domain.repository.TeamIdsString
-import org.junit.Test
-
+import nl.entreco.domain.setup.game.CreateGameRequest
import org.junit.Before
+import org.junit.Test
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@@ -20,19 +17,19 @@ import org.mockito.MockitoAnnotations
*/
class RetrieveLatestGameUsecaseTest {
- @Mock private lateinit var mockGameRepository : GameRepository
- @Mock private lateinit var mockDone : (FetchLatestGameResponse) -> Unit
- @Mock private lateinit var mockFail : (Throwable) -> Unit
+ @Mock private lateinit var mockGameRepository: GameRepository
+ @Mock private lateinit var mockDone: (FetchLatestGameResponse) -> Unit
+ @Mock private lateinit var mockFail: (Throwable) -> Unit
private val fg = TestForeground()
private val bg = TestBackground()
- private val gameId : Long = 44
- private val teamids = TeamIdsString("1,2,3,4|5,6,7,8")
- private val createRequest = CreateGameRequest(501, 1,2,3)
+ private val gameId: Long = 44
+ private val teamids = "1,2,3,4|5,6,7,8"
+ private val createRequest = CreateGameRequest(501, 1, 2, 3)
- private lateinit var subject : RetrieveLatestGameUsecase
- private lateinit var gavenLatestGame : FetchLatestGameResponse
+ private lateinit var subject: RetrieveLatestGameUsecase
+ private lateinit var gavenLatestGame: FetchLatestGameResponse
@Before
fun setUp() {
@@ -56,12 +53,12 @@ class RetrieveLatestGameUsecaseTest {
}
private fun givenLatestGameExists() {
- gavenLatestGame = FetchLatestGameResponse(gameId, teamids, createRequest)
+ gavenLatestGame = FetchLatestGameResponse(gameId, teamids, createRequest.startScore, createRequest.startIndex, createRequest.numLegs, createRequest.numSets)
whenever(mockGameRepository.fetchLatest()).thenReturn(gavenLatestGame)
}
private fun givenLatestGameDoesNotExists() {
- gavenLatestGame = FetchLatestGameResponse(gameId, teamids, createRequest)
+ gavenLatestGame = FetchLatestGameResponse(gameId, teamids, createRequest.startScore, createRequest.startIndex, createRequest.numLegs, createRequest.numSets)
whenever(mockGameRepository.fetchLatest()).thenThrow(IllegalStateException("no game available"))
}
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/BaseGameTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/BaseGameTest.kt
index b2e31400..5eac3431 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/BaseGameTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/BaseGameTest.kt
@@ -8,7 +8,8 @@ import org.junit.Assert
*/
abstract class BaseGameTest(val subject: Game = Game(0, TestProvider().arbiter())) {
- private val teams = TestProvider().teams()
+ protected val testProvider = TestProvider()
+ private val teams = testProvider.teams()
private val startIndex = TestProvider().startIndex()
protected fun whenDartsThrown(vararg turns: Turn) {
@@ -29,4 +30,5 @@ abstract class BaseGameTest(val subject: Game = Game(0, TestProvider().arbiter()
protected fun sixty() = Turn(Dart.SINGLE_20, Dart.SINGLE_20, Dart.SINGLE_20)
protected fun oneEighty() = Turn(Dart.TRIPLE_20, Dart.TRIPLE_20, Dart.TRIPLE_20)
+ protected fun oneFourOne() = Turn(Dart.TRIPLE_20, Dart.TRIPLE_19, Dart.DOUBLE_12)
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/GameTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/GameTest.kt
index 599d31d4..af558d13 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/GameTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/GameTest.kt
@@ -1,6 +1,6 @@
package nl.entreco.domain.model
-import org.junit.Assert.assertNotNull
+import org.junit.Assert.*
import org.junit.Test
class GameTest : BaseGameTest() {
@@ -41,4 +41,85 @@ class GameTest : BaseGameTest() {
assertScore(321, 321)
}
+
+ @Test
+ fun `it should keep track of previous score for stats (start)`() {
+ givenGameStarted()
+ assertEquals(Score(), subject.previousScore())
+ }
+
+ @Test
+ fun `it should keep track of previous score for stats (turn 1)`() {
+ givenGameStarted()
+ whenDartsThrown(sixty())
+ assertEquals(Score(501), subject.previousScore())
+ }
+
+ @Test
+ fun `it should keep track of previous score for stats (turn 2)`() {
+ givenGameStarted()
+ whenDartsThrown(sixty(), oneEighty())
+ assertEquals(Score(501), subject.previousScore())
+ }
+
+ @Test
+ fun `it should keep track of previous score for stats (turn 3)`() {
+ givenGameStarted()
+ whenDartsThrown(sixty(), sixty(), sixty())
+ assertEquals(Score(501-60), subject.previousScore())
+ }
+
+ @Test
+ fun `it should not report breaks when game just started`() {
+ givenGameStarted()
+ assertFalse(subject.wasBreakMade(testProvider.player1()))
+ assertFalse(subject.wasBreakMade(testProvider.player2()))
+ }
+
+ @Test
+ fun `it should know when no break was made - normal case`() {
+ givenGameStarted()
+ whenDartsThrown(sixty(), oneEighty())
+ assertFalse(subject.wasBreakMade(testProvider.player1()))
+ assertFalse(subject.wasBreakMade(testProvider.player2()))
+ }
+
+ @Test
+ fun `it should know when no break was made - opponent break`() {
+ givenGameStarted()
+ whenDartsThrown(sixty(), oneEighty(), sixty(), oneEighty(), sixty(), oneFourOne())
+ assertFalse(subject.wasBreakMade(testProvider.player1()))
+ }
+
+ @Test
+ fun `it should know when break was made`() {
+ givenGameStarted()
+ whenDartsThrown(sixty(), oneEighty(), sixty(), oneEighty(), sixty(), oneFourOne())
+ assertTrue(subject.wasBreakMade(testProvider.player2()))
+ }
+
+ @Test
+ fun `it should know if match,set or let was started`() {
+ givenGameStarted()
+ assertTrue(subject.isNewMatchLegOrSet())
+ whenDartsThrown(oneEighty(), sixty(), oneEighty(), sixty())
+ assertFalse(subject.isNewMatchLegOrSet())
+ whenDartsThrown(oneFourOne())
+ assertTrue(subject.isNewMatchLegOrSet())
+ }
+
+ @Test
+ fun `it should increment turnCount after a turn`() {
+ givenGameStarted()
+ assertEquals(0, subject.getTurnCount())
+ whenDartsThrown(sixty())
+ assertEquals(1, subject.getTurnCount())
+ }
+
+ @Test
+ fun `it should increment turnCount after multiple turns`() {
+ givenGameStarted()
+ whenDartsThrown(sixty(), sixty(), oneEighty(), oneFourOne())
+ assertEquals(4, subject.getTurnCount())
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/NextTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/NextTest.kt
index f5eea7f9..cfe51032 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/NextTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/NextTest.kt
@@ -2,7 +2,7 @@ package nl.entreco.domain.model
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.model.players.Team
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
import org.junit.Test
/**
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/StatTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/StatTest.kt
new file mode 100644
index 00000000..24266fe9
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/StatTest.kt
@@ -0,0 +1,85 @@
+package nl.entreco.domain.model
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Test
+
+/**
+ * Created by entreco on 23/01/2018.
+ */
+class StatTest {
+
+ @Test
+ fun `it should handle adding nulls`() {
+ val stat = statWith()
+ assertEquals(stat, stat + null)
+ }
+
+ @Test
+ fun `it should handle being added to null`() {
+ val stat = statWith()
+ assertNotEquals(null, null + stat)
+ assertNotEquals(stat, null + stat)
+ }
+
+ @Test
+ fun `it should add totalScore-stats together`() {
+ assertEquals(42, totalScore(20, 20, 2).totalScore)
+ }
+
+ @Test
+ fun `it should add numDarts-stats together`() {
+ assertEquals(32, numDarts(20, 10, 2).nDarts)
+ }
+
+ @Test
+ fun `it should add 180s-stats together`() {
+ assertEquals(2, n180s(-1, 1, 2).n180)
+ }
+
+ @Test
+ fun `it should add 140-stats together`() {
+ assertEquals(6, n140s(1, 2, 3).n140)
+ }
+
+ @Test
+ fun `it should add 100-stats together`() {
+ assertEquals(3, n100s(1, 1, 1).n100)
+ }
+
+ private fun totalScore(score: Int, vararg scores: Int): Stat {
+ var stat = statWith(totalScore = score)
+ scores.map { statWith(totalScore = it) }.forEach { stat += it }
+ return stat
+ }
+
+ private fun numDarts(dart: Int, vararg darts: Int): Stat {
+ var stat = statWith(nDarts = dart)
+ darts.map { statWith(nDarts = it) }.forEach { stat += it }
+ return stat
+ }
+
+ private fun n180s(dart: Int, vararg darts: Int): Stat {
+ var stat = statWith(n180 = dart)
+ darts.map { statWith(n180 = it) }.forEach { stat += it }
+ return stat
+ }
+
+ private fun n140s(dart: Int, vararg darts: Int): Stat {
+ var stat = statWith(n140 = dart)
+ darts.map { statWith(n140 = it) }.forEach { stat += it }
+ return stat
+ }
+
+ private fun n100s(dart: Int, vararg darts: Int): Stat {
+ var stat = statWith(n100 = dart)
+ darts.map { statWith(n100 = it) }.forEach { stat += it }
+ return stat
+ }
+
+ private fun statWith(playerId: Long = 0, totalScore: Int = 0, nDarts: Int = 0,
+ n180: Int = 0, n140: Int = 0, n100: Int = 0, nAtCheckout: Int = 0, nCheckouts: Int = 0,
+ nBreaks: Int = 0, highest: List = emptyList(), highestCo: List = emptyList()): Stat {
+ return Stat(playerId, totalScore, nDarts, n180, n140, n100, nAtCheckout, nCheckouts, nBreaks, highest, highestCo)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/TurnTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/TurnTest.kt
index 4a1defb5..169b2ac0 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/TurnTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/TurnTest.kt
@@ -1,9 +1,8 @@
package nl.entreco.domain.model
+import org.junit.Assert.assertEquals
import org.junit.Test
-import org.junit.Assert.*
-
/**
* Created by Entreco on 27/11/2017.
*/
@@ -31,7 +30,6 @@ class TurnTest {
assertEquals(Dart.NONE, Turn().first())
}
-
@Test
fun `second should be NONE, for empty turn`() {
assertEquals(Dart.NONE, Turn().second())
@@ -74,6 +72,11 @@ class TurnTest {
assertEquals(3, Turn().dartsLeft())
}
+ @Test
+ fun `darts used should be 0, for empty turn`() {
+ assertEquals(0, Turn().dartsUsed())
+ }
+
@Test
fun `total should be 0, for empty turn`() {
assertEquals(0, Turn().total())
@@ -99,6 +102,21 @@ class TurnTest {
assertEquals(0, turn.dartsLeft())
}
+ @Test
+ fun `it should update darts used`() {
+ var turn = Turn()
+ assertEquals(0, turn.dartsUsed())
+
+ turn += Dart.SINGLE_20
+ assertEquals(1, turn.dartsUsed())
+
+ turn += Dart.TRIPLE_2
+ assertEquals(2, turn.dartsUsed())
+
+ turn += Dart.BULL
+ assertEquals(3, turn.dartsUsed())
+ }
+
@Test(expected = IllegalStateException::class)
fun `it is NOT allowed to add NONE to a turn`() {
Turn() + Dart.NONE
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/PlayerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/PlayerTest.kt
index 934dcf55..2497d635 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/PlayerTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/PlayerTest.kt
@@ -1,9 +1,8 @@
package nl.entreco.domain.model.players
+import org.junit.Assert.assertEquals
import org.junit.Test
-import org.junit.Assert.*
-
/**
* Created by Entreco on 16/12/2017.
*/
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/TeamTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/TeamTest.kt
index c901b970..3cf99d8e 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/TeamTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/model/players/TeamTest.kt
@@ -41,4 +41,14 @@ class TeamTest{
fun `it should not contain player3`() {
assertFalse(subject.contains(player3))
}
+
+ @Test
+ fun `it should contain player with id 0`() {
+ assertTrue(subject.contains(0L))
+ }
+
+ @Test
+ fun `it should NOT contain player with id 1`() {
+ assertFalse(subject.contains(1L))
+ }
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterStatsTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterStatsTest.kt
new file mode 100644
index 00000000..cc58d9f5
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterStatsTest.kt
@@ -0,0 +1,102 @@
+package nl.entreco.domain.play
+
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.model.Dart
+import nl.entreco.domain.model.Next
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.model.players.Team
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 23/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class ArbiterStatsTest{
+
+ @Mock private lateinit var mockNext : Next
+ private val givenStartIndex = 0
+ private val givenTeams = arrayOf(Team(arrayOf(Player("1"))), Team(arrayOf(Player("2"))))
+ private val givenScore = Score()
+ private lateinit var subject : Arbiter
+
+ @Test
+ fun `it should keep track of turns`() {
+ givenSubject()
+ whenStarting()
+ thenTurnCounterIs(0)
+ }
+
+ @Test
+ fun `it should udpate turn counter after handling valid turn`() {
+ givenSubject()
+ whenStarting()
+ whenHandling(Turn(Dart.SINGLE_1))
+ thenTurnCounterIs(1)
+ }
+
+ @Test
+ fun `it should NOT reset turn counter for new leg`() {
+ givenSubject()
+ whenStarting()
+ whenHandling(Turn(Dart.SINGLE_1, Dart.TEST_D250))
+ thenTurnCounterIs(1)
+ }
+
+ @Test
+ fun `it should NOT increment turn counter when busting`() {
+ givenSubject()
+ whenStarting()
+ whenHandling(Turn(Dart.TEST_501, Dart.TEST_D250, Dart.TEST_D250))
+ thenTurnCounterIs(0)
+ }
+
+ @Test
+ fun `it should track previous score`() {
+ givenSubject()
+ whenStarting()
+ thenPreviousScoreIs(501)
+ }
+
+ @Test
+ fun `it should track previous score after handling 1 turn`() {
+ givenSubject()
+ whenStarting()
+ whenHandling(Turn(Dart.SINGLE_1))
+ thenPreviousScoreIs(501)
+ }
+
+ @Test
+ fun `it should track previous score when leg finished`() {
+ givenSubject()
+ whenStarting()
+ whenHandling(Turn(Dart.SINGLE_1, Dart.TEST_D250))
+ thenPreviousScoreIs(501)
+ }
+
+ private fun givenSubject() {
+ subject = Arbiter(givenScore)
+ }
+
+ private fun whenStarting() {
+ subject.start(givenStartIndex, givenTeams)
+ }
+
+ private fun whenHandling(turn: Turn) {
+ whenever(mockNext.team).thenReturn(givenTeams[givenStartIndex])
+ subject.handle(turn, mockNext)
+ }
+
+ private fun thenTurnCounterIs(expected: Int) {
+ assertEquals(expected, subject.getTurnCount())
+ }
+
+ private fun thenPreviousScoreIs(expected: Int) {
+ assertEquals(expected, subject.getPreviousScore().score)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterTest.kt
index fd480b55..afc7fcee 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ArbiterTest.kt
@@ -6,6 +6,7 @@ import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
import nl.entreco.domain.model.Turn
import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -26,6 +27,11 @@ class ArbiterTest {
}
}
+ @Test
+ fun `it should create TurnHandler`() {
+ assertNotNull(subject.turnHandler)
+ }
+
@Test
fun `it should not start new leg if zero is scored`() {
subject.handle(Turn(Dart.ZERO, Dart.ZERO, Dart.ZERO), next)
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorAtDoubleTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorAtDoubleTest.kt
new file mode 100644
index 00000000..d203cd19
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorAtDoubleTest.kt
@@ -0,0 +1,89 @@
+package nl.entreco.domain.play
+
+import nl.entreco.domain.model.Dart
+import nl.entreco.domain.model.Turn
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+class ScoreEstimatorAtDoubleTest {
+
+ private val subject = ScoreEstimator()
+
+ @Test
+ fun `it should return 3 for 40 (0,0,0)`() {
+ assertEquals(3, subject.atDouble(Turn(Dart.ZERO, Dart.ZERO, Dart.ZERO), 40))
+ }
+
+ @Test
+ fun `it should return 3 for 40 (2,0,0)`() {
+ assertEquals(3, subject.atDouble(Turn(Dart.SINGLE_2, Dart.ZERO, Dart.ZERO), 40))
+ }
+
+ @Test
+ fun `it should return 2 for 40 (2,1,0)`() {
+ assertEquals(2, subject.atDouble(Turn(Dart.SINGLE_2, Dart.SINGLE_1, Dart.ZERO), 40))
+ }
+
+ @Test
+ fun `it should return 2 for 40 (1,1,0)`() {
+ assertEquals(2, subject.atDouble(Turn(Dart.SINGLE_1, Dart.SINGLE_1, Dart.ZERO), 40))
+ }
+
+ @Test
+ fun `it should return 1 for 40 (1,0,0)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.SINGLE_1, Dart.ZERO, Dart.ZERO), 40))
+ }
+
+ @Test
+ fun `it should return 1 for 40 (1,2,0)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.SINGLE_1, Dart.SINGLE_2, Dart.ZERO), 40))
+ }
+
+ @Test
+ fun `it should return 1 for 40 (1,2,2)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.SINGLE_1, Dart.SINGLE_2, Dart.SINGLE_2), 40))
+ }
+
+ @Test
+ fun `it should return 0 for 41 (2,2,2)`() {
+ assertEquals(0, subject.atDouble(Turn(Dart.SINGLE_2, Dart.SINGLE_2, Dart.SINGLE_2), 41))
+ }
+
+ @Test
+ fun `it should return 1 for 141 (T20,T19,2)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.TRIPLE_20, Dart.TRIPLE_19, Dart.SINGLE_2), 141))
+ }
+
+ @Test
+ fun `it should return 1 for 141 (T19,T20,2)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.TRIPLE_19, Dart.TRIPLE_20, Dart.SINGLE_2), 141))
+ }
+
+ @Test
+ fun `it should return 1 for 170 (T20,T20,2)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.TRIPLE_20, Dart.TRIPLE_20, Dart.SINGLE_2), 170))
+ }
+
+ @Test
+ fun `it should return 1 for 167 (T20,T19,2)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.TRIPLE_20, Dart.TRIPLE_19, Dart.SINGLE_2), 167))
+ }
+
+ @Test
+ fun `it should return 1 for 167 (T19,T20,2)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.TRIPLE_19, Dart.TRIPLE_20, Dart.SINGLE_2), 167))
+ }
+
+ @Test
+ fun `it should return 1 for 40 (D20)`() {
+ assertEquals(1, subject.atDouble(Turn(Dart.DOUBLE_20), 40))
+ }
+
+ @Test
+ fun `it should return 3 for 40 (0,0,D20)`() {
+ assertEquals(3, subject.atDouble(Turn(Dart.ZERO, Dart.ZERO, Dart.DOUBLE_20), 40))
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorTest.kt
index 7e95ee37..0e9c50cb 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/ScoreEstimatorTest.kt
@@ -1,7 +1,7 @@
package nl.entreco.domain.play
import nl.entreco.domain.model.Turn
-import org.junit.Assert.*
+import org.junit.Assert.assertEquals
import org.junit.Test
/**
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/GetFinishUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/finish/GetFinishUsecaseTest.kt
similarity index 87%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/GetFinishUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/finish/GetFinishUsecaseTest.kt
index 65a2b258..54a989c3 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/GetFinishUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/finish/GetFinishUsecaseTest.kt
@@ -1,13 +1,12 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.finish
import com.nhaarman.mockito_kotlin.verify
-import nl.entreco.domain.Logger
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.TestBackground
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.TestBackground
import nl.entreco.domain.model.Dart
import nl.entreco.domain.model.Score
-import nl.entreco.domain.play.ScoreEstimator
import nl.entreco.domain.model.Turn
+import nl.entreco.domain.play.ScoreEstimator
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Before
@@ -23,8 +22,7 @@ import org.mockito.junit.MockitoJUnitRunner
class GetFinishUsecaseTest {
private val mockBg: Background = TestBackground()
- @Mock private lateinit var mockLogger: Logger
- @Mock private lateinit var mockResult: (String) -> Unit
+ @Mock private lateinit var mockResult: (GetFinishResponse) -> Unit
lateinit var subject: GetFinishUsecase
@Before
@@ -34,18 +32,20 @@ class GetFinishUsecaseTest {
@Test
fun `it should report result`() {
- subject.calculate(Score(170), Turn(), 20, mockResult)
- verify(mockResult).invoke("T20 T20 BULL")
+ subject.calculate(GetFinishRequest(Score(170), Turn(), 20), mockResult)
+ verify(mockResult).invoke(GetFinishResponse("T20 T20 BULL"))
}
@Test
fun `it should return empty for scores higher than 170`() {
- assertEquals("", subject.calculateInBack(171, Turn(), 20))
+ val turn = Turn()
+ assertEquals("", subject.calculateInBack(171, turn.dartsLeft(), turn.total(), 20))
}
@Test
fun `it should return T20 T20 BULL for score of 170`() {
- assertEquals("T20 T20 BULL", subject.calculateInBack(170, Turn(), 20))
+ val turn = Turn()
+ assertEquals("T20 T20 BULL", subject.calculateInBack(170, turn.dartsLeft(), turn.total(), 20))
}
@Test
@@ -120,12 +120,12 @@ class GetFinishUsecaseTest {
}
private fun verifyNotPossible(scored: Int, turn: Turn) {
- val finish = subject.calculateInBack(scored, turn, 20)
+ val finish = subject.calculateInBack(scored, turn.dartsLeft(), turn.total(), 20)
assertEquals("scored: $scored finish: $finish", subject.notPossible, finish)
}
private fun verifyDartsNeeded(scored: Int, turn: Turn, numDarts: Int) {
- val finish = subject.calculateInBack(scored, turn, 20)
+ val finish = subject.calculateInBack(scored, turn.dartsLeft(), turn.total(), 20)
val thrown = ScoreEstimator().guess(scored, false)
assertNotEquals("scored: $scored finish: $finish", subject.notPossible, finish)
assertEquals("scored: $scored finish: $finish", numDarts, finish.split(" ").size)
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/BustEventListenerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/BustEventListenerTest.kt
index 8a2f8235..b7a7a3a9 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/BustEventListenerTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/BustEventListenerTest.kt
@@ -1,12 +1,12 @@
package nl.entreco.domain.play.listeners
-import nl.entreco.domain.play.listeners.events.BustEvent
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.listeners.events.BustEvent
import org.junit.Assert
import org.junit.Test
import java.util.concurrent.atomic.AtomicBoolean
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NineDartEventListenerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NineDartEventListenerTest.kt
new file mode 100644
index 00000000..e3b55791
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NineDartEventListenerTest.kt
@@ -0,0 +1,80 @@
+package nl.entreco.domain.play.listeners
+
+import nl.entreco.domain.model.Next
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.listeners.events.NineDartEvent
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import java.util.concurrent.atomic.AtomicBoolean
+
+
+class NineDartEventListenerTest : SpecialEventListenerTest() {
+
+ @Test
+ fun `it should notify about NineDart event when (180, 321)`() {
+ val subject = NineDartEventListener()
+ subject.onScored(`180`(), 321)
+ assertTrue(subject.wasPossible())
+ }
+
+ @Test
+ fun `it should notify about NineDart event when (177, 324)`() {
+ val subject = NineDartEventListener()
+ subject.onScored(`177`(), 324)
+ assertTrue(subject.wasPossible())
+ }
+
+ @Test
+ fun `shortCut for all possibilities`() {
+ shouldBePossible(`180`(), `180`())
+ shouldBePossible(`180`(), `171`())
+ shouldBePossible(`171`(), `180`())
+ shouldBePossible(`177`(), `180`())
+ shouldBePossible(`180`(), `177`())
+ shouldBePossible(`177`(), `177`())
+ shouldBePossible(`167`(), `167`())
+ }
+
+ private fun shouldBePossible(vararg turns: Turn) {
+ val subject = NineDartEventListener()
+ var score = 501
+ turns.forEach {
+ score -= it.total()
+ subject.onScored(it, score)
+ assertTrue("not possible score:$score with turns: $turns", subject.wasPossible())
+ }
+ }
+
+ @Test
+ fun `it should NOT notify about NineDart event when (60, 321)`() {
+ val subject = NineDartEventListener()
+ subject.onScored(`60`(), 321)
+ assertFalse(subject.wasPossible())
+ }
+
+ private class NineDartEventListener(private val check: AtomicBoolean = AtomicBoolean(false)) : SpecialEventListener {
+ private val isPossible = AtomicBoolean(false)
+ private val player = Player("Nine Dart Master")
+
+ override fun handle(event: NineDartEvent) {
+ check.set(true)
+ isPossible.set(event.isPossible())
+ }
+
+ fun onScored(turn: Turn, score: Int) {
+ val scores = arrayOf(Score(score))
+ val team = Team(arrayOf(player))
+ val next = Next(State.NORMAL, team, 0, player, scores[0])
+ onSpecialEvent(next, turn, player, scores)
+ }
+
+ fun wasPossible(): Boolean {
+ return isPossible.get()
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NoScoreEventListenerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NoScoreEventListenerTest.kt
index 1c2c8882..62348925 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NoScoreEventListenerTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/NoScoreEventListenerTest.kt
@@ -1,12 +1,12 @@
package nl.entreco.domain.play.listeners
-import nl.entreco.domain.play.listeners.events.NoScoreEvent
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.listeners.events.NoScoreEvent
import org.junit.Assert
import org.junit.Test
import java.util.concurrent.atomic.AtomicBoolean
@@ -23,13 +23,6 @@ class NoScoreEventListenerTest : SpecialEventListenerTest() {
Assert.assertTrue(subject.wasNotified())
}
- @Test
- fun `it should not notify about 180 event when 180 was scored`() {
- val subject = NoScoreEventListener()
- subject.onScored(`180`())
- Assert.assertFalse(subject.wasNotified())
- }
-
@Test
fun `it should not notify about 180 event when no 180 was scored`() {
val subject = NoScoreEventListener()
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/OneEightyEventListenerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/OneEightyEventListenerTest.kt
deleted file mode 100644
index 1178d4a3..00000000
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/OneEightyEventListenerTest.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-package nl.entreco.domain.play.listeners
-
-import nl.entreco.domain.play.listeners.events.OneEightyEvent
-import nl.entreco.domain.model.Next
-import nl.entreco.domain.model.Score
-import nl.entreco.domain.model.Turn
-import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
-import nl.entreco.domain.model.players.Team
-import org.junit.Assert
-import org.junit.Test
-import java.util.concurrent.atomic.AtomicBoolean
-
-/**
- * Created by Entreco on 05/12/2017.
- */
-
-class OneEightyEventListenerTest : SpecialEventListenerTest() {
- @Test
- fun `it should notify about 180 event when 180 was scored`() {
- val subject = OneEightEventListener()
- subject.onScored(`180`())
- Assert.assertTrue(subject.wasNotified())
- }
-
- @Test
- fun `it should not notify about 180 event when no 180 was scored`() {
- val subject = OneEightEventListener()
- subject.onScored(`60`())
- Assert.assertFalse(subject.wasNotified())
- }
-
- @Test
- fun `it should not notify about NoScore event when NoScore was scored`() {
- val subject = OneEightEventListener()
- subject.onScored(`No Score`())
- Assert.assertFalse(subject.wasNotified())
- }
-
- private class OneEightEventListener(private val check: AtomicBoolean = AtomicBoolean(false)) : SpecialEventListener {
-
- private val player = Player("180 thrower")
- private val team = Team(arrayOf(player))
- private val score = Score()
-
- override fun handle(event: OneEightyEvent) {
- check.set(true)
- }
-
- fun onScored(turn: Turn) {
- onSpecialEvent(Next(State.NORMAL, team, 0, player, score), turn, player, arrayOf(score))
- }
-
- fun wasNotified(): Boolean {
- return check.get()
- }
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/SpecialEventListenerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/SpecialEventListenerTest.kt
index ea452ac8..8445fc07 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/SpecialEventListenerTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/SpecialEventListenerTest.kt
@@ -8,6 +8,9 @@ import nl.entreco.domain.model.Turn
*/
abstract class SpecialEventListenerTest {
fun `180`(): Turn = Turn(Dart.TRIPLE_20, Dart.TRIPLE_20, Dart.TRIPLE_20)
+ fun `177`(): Turn = Turn(Dart.TRIPLE_20, Dart.TRIPLE_20, Dart.TRIPLE_19)
+ fun `171`(): Turn = Turn(Dart.TRIPLE_19, Dart.TRIPLE_19, Dart.TRIPLE_19)
+ fun `167`(): Turn = Turn(Dart.TRIPLE_20, Dart.TRIPLE_19, Dart.BULL)
fun `60`(): Turn = Turn(Dart.SINGLE_20, Dart.SINGLE_20, Dart.SINGLE_20)
fun `No Score`(): Turn = Turn(Dart.ZERO, Dart.ZERO, Dart.ZERO)
fun `bust`(): Turn = Turn(Dart.TEST_501, Dart.TEST_501, Dart.TEST_501)
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/ThrownEventListenerTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/ThrownEventListenerTest.kt
index 187a1546..677ef69f 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/ThrownEventListenerTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/ThrownEventListenerTest.kt
@@ -1,12 +1,12 @@
package nl.entreco.domain.play.listeners
-import nl.entreco.domain.play.listeners.events.ThrownEvent
import nl.entreco.domain.model.Next
import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.State
import nl.entreco.domain.model.Turn
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.State
import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.listeners.events.ThrownEvent
import org.junit.Assert
import org.junit.Test
import java.util.concurrent.atomic.AtomicBoolean
@@ -16,14 +16,6 @@ import java.util.concurrent.atomic.AtomicBoolean
*/
class ThrownEventListenerTest : SpecialEventListenerTest() {
- @Test
- fun `it should notify when darts where thrown`() {
- val subject = ThrownEventListener()
- subject.onThrown(`180`())
- Assert.assertTrue(subject.wasNotified())
- Assert.assertEquals("T20 T20 T20", subject.describe())
- }
-
@Test
fun `it should notify about throw when busting`() {
val subject = ThrownEventListener()
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/events/NineDartEventTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/events/NineDartEventTest.kt
new file mode 100644
index 00000000..abce141d
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/listeners/events/NineDartEventTest.kt
@@ -0,0 +1,47 @@
+package nl.entreco.domain.play.listeners.events
+
+import com.nhaarman.mockito_kotlin.verifyZeroInteractions
+import nl.entreco.domain.model.players.Player
+import org.junit.Assert.*
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class NineDartEventTest {
+ @Mock private lateinit var mockBy : Player
+ private lateinit var subject: NineDartEvent
+
+ @Test
+ fun `everything is possible`() {
+ givenSubject(true)
+ assertTrue(subject.isPossible())
+ }
+
+ @Test
+ fun `except when isPossible is false`() {
+ givenSubject(false)
+ assertFalse(subject.isPossible())
+ }
+
+ @Test
+ fun `should not interact with player`() {
+ givenSubject(true)
+ verifyZeroInteractions(mockBy)
+ }
+
+ @Test
+ fun `should return player`() {
+ givenSubject(false)
+ assertEquals(mockBy, subject.by())
+ }
+
+ private fun givenSubject(isPossible: Boolean) {
+ subject = NineDartEvent(isPossible, mockBy)
+ }
+
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/MarkGameAsFinishedUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/MarkGameAsFinishedUsecaseTest.kt
new file mode 100644
index 00000000..99974d93
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/MarkGameAsFinishedUsecaseTest.kt
@@ -0,0 +1,63 @@
+package nl.entreco.domain.play.start
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
+import nl.entreco.domain.repository.GameRepository
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 09/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class MarkGameAsFinishedUsecaseTest {
+
+ @Mock private lateinit var mockGameRepository: GameRepository
+ private val bg = TestBackground()
+ private val fg = TestForeground()
+ private lateinit var subject: MarkGameAsFinishedUsecase
+
+ private var givenId: Long = -1
+ private lateinit var givenMarkAsFinishedRequest: MarkGameAsFinishedRequest
+
+ @Test
+ fun `it should execute update`() {
+ givenSubject()
+ whenMarkingGameAsFinished(244)
+ thenGameIsMarkedAsFinished()
+ }
+
+ @Test
+ fun `it should not handle any errors`() {
+ givenSubject()
+ whenMarkingGameAsFinishedFails(RuntimeException("oops, db corrupt"))
+ thenGameIsMarkedAsFinished()
+ }
+
+ private fun givenSubject() {
+ subject = MarkGameAsFinishedUsecase(mockGameRepository, bg, fg)
+ }
+
+ private fun whenMarkingGameAsFinished(gameId: Long) {
+ givenId = gameId
+ givenMarkAsFinishedRequest = MarkGameAsFinishedRequest(gameId)
+ subject.exec(givenMarkAsFinishedRequest)
+ }
+
+ private fun whenMarkingGameAsFinishedFails(err: Throwable) {
+ givenId = 666
+ givenMarkAsFinishedRequest = MarkGameAsFinishedRequest(givenId)
+ whenever(mockGameRepository.finish(any())).thenThrow(err)
+ subject.exec(givenMarkAsFinishedRequest)
+ }
+
+ private fun thenGameIsMarkedAsFinished() {
+ verify(mockGameRepository).finish(givenId)
+ }
+
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/Play01ResponseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/Play01ResponseTest.kt
new file mode 100644
index 00000000..df113a33
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/Play01ResponseTest.kt
@@ -0,0 +1,48 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.model.Game
+import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.settings.ScoreSettings
+import org.junit.Assert.assertEquals
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class Play01ResponseTest {
+
+ @Mock private lateinit var mockGame: Game
+ @Mock private lateinit var mockSettings: ScoreSettings
+ @Mock private lateinit var mockTeam1: Team
+ @Mock private lateinit var mockTeam2: Team
+
+ @Test
+ fun `it should report equals on same instance`() {
+ val response = Play01Response(mockGame, mockSettings, arrayOf(mockTeam1, mockTeam2), "")
+ assertEquals(response, response)
+ }
+
+ @Test
+ fun `it should report equals on new instance`() {
+ val response1 = Play01Response(mockGame, mockSettings, arrayOf(mockTeam1, mockTeam2), "")
+ val response2 = Play01Response(mockGame, mockSettings, arrayOf(mockTeam1, mockTeam2),"")
+ assertEquals(response1, response2)
+ }
+
+ @Test
+ fun `it should report equal hashcode`() {
+ val response = Play01Response(mockGame, mockSettings, arrayOf(mockTeam1, mockTeam2), "")
+ assertEquals(response.hashCode(), response.hashCode())
+ }
+
+ @Test
+ fun `it should report equals hashcode on new instance`() {
+ val response1 = Play01Response(mockGame, mockSettings, arrayOf(mockTeam1, mockTeam2), "")
+ val response2 = Play01Response(mockGame, mockSettings, arrayOf(mockTeam1, mockTeam2), "")
+ assertEquals(response1.hashCode(), response2.hashCode())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/Play01UsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/Play01UsecaseTest.kt
new file mode 100644
index 00000000..e6b310fb
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/Play01UsecaseTest.kt
@@ -0,0 +1,201 @@
+package nl.entreco.domain.play.start
+
+import com.nhaarman.mockito_kotlin.*
+import nl.entreco.domain.Logger
+import nl.entreco.domain.model.*
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.model.players.Team
+import nl.entreco.domain.play.stats.*
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by Entreco on 17/12/2017.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class Play01UsecaseTest {
+
+ private val gameId: Long = 42
+ private val teams = arrayOf(Team(arrayOf(Player("1"), Player("2"))), Team(arrayOf(Player("3"))), Team(arrayOf(Player("4"))))
+ private val teamIds = "1,2|3|4"
+ private val startScore = 1001
+ private val startIndex = 2
+ private val numLegs = 3
+ private val numSets = 10
+ private val req: Play01Request = Play01Request(gameId, teamIds, startScore, startIndex, numLegs, numSets)
+
+ private val teamOkCaptor = argumentCaptor<(RetrieveTeamsResponse) -> Unit>()
+ private val gameOkCaptor = argumentCaptor<(RetrieveGameResponse) -> Unit>()
+ private val turnOkCaptor = argumentCaptor<(RetrieveTurnsResponse) -> Unit>()
+ private val storeOkCaptor = argumentCaptor<(StoreTurnResponse) -> Unit>()
+ private val failCaptor = argumentCaptor<(Throwable) -> Unit>()
+
+ @Mock private lateinit var done: (Play01Response) -> Unit
+ @Mock private lateinit var fail: (Throwable) -> Unit
+ @Mock private lateinit var mockGameUc: RetrieveGameUsecase
+ @Mock private lateinit var mockTurnsUc: RetrieveTurnsUsecase
+ @Mock private lateinit var mockTeamUc: RetrieveTeamsUsecase
+ @Mock private lateinit var mockTurnUc: StoreTurnUsecase
+ @Mock private lateinit var mockStatsUc: StoreMetaUsecase
+ @Mock private lateinit var mockUndo: UndoTurnUsecase
+ @Mock private lateinit var mockMarkUc: MarkGameAsFinishedUsecase
+ @Mock private lateinit var mockLogger: Logger
+ @Mock private lateinit var mockGame: Game
+ @Mock private lateinit var mockDone: (Long, Long) -> Unit
+
+ private val mockTurns = emptyList>()
+ private lateinit var expectedTurnRequest: StoreTurnRequest
+ private lateinit var expectedUndoRequest: UndoTurnRequest
+ private lateinit var expectedTurnMeta: TurnMeta
+ private lateinit var givenMarkFinishRequest: MarkGameAsFinishedRequest
+
+ private lateinit var subject: Play01Usecase
+
+ @Before
+ fun setUp() {
+ subject = Play01Usecase(mockGameUc, mockTurnsUc, mockTeamUc, mockTurnUc, mockStatsUc, mockUndo, mockMarkUc, mockLogger)
+ }
+
+ @Test
+ fun loadGameAndStart() {
+ whenLoadingGameAndStarting()
+ whenTeamsAreRetrieved()
+ whenGameIsLoaded()
+ whenTurnsRetrieved()
+ thenGameIsStarted()
+ }
+
+ @Test
+ fun loadGameWithTeamErrors() {
+ whenLoadingGameAndStarting()
+ whenTeamsAreNotRetrieved()
+ thenGameIsNotStarted()
+ }
+
+ @Test
+ fun loadGameWithGameErrors() {
+ whenLoadingGameAndStarting()
+ whenTeamsAreRetrieved()
+ whenGameIsNotLoaded()
+ thenGameIsNotStarted()
+ }
+
+ @Test
+ fun storeTurn() {
+ whenStoringTurn(Turn(Dart.DOUBLE_1, Dart.DOUBLE_15))
+ thenTurnIsStored()
+ }
+
+ @Test
+ fun `it should store stats when storing turns succeeds`() {
+ whenStoringTurn(Turn(Dart.DOUBLE_1, Dart.DOUBLE_15))
+ whenStoringTurnSucceeds(12L)
+ thenStatsAreStored()
+ }
+
+ @Test
+ fun `it should log error when storing turns fails`() {
+ whenStoringTurn(Turn(Dart.DOUBLE_1, Dart.DOUBLE_15))
+ whenStoringTurnFails(RuntimeException("Something went wrong"))
+ thenErrorIsLogged()
+ }
+
+ @Test
+ fun markGameAsFinished() {
+ whenGameIsFinished()
+ thenGameIsMarkedAsFinished()
+ }
+
+ @Test
+ fun `it should undo last turn`() {
+ whenUndoLastTurn()
+ thenUndoUsecaseIsExecuted()
+ }
+
+ private fun whenStoringTurn(turn: Turn) {
+ expectedTurnRequest = StoreTurnRequest(0, gameId, turn)
+ expectedTurnMeta = TurnMeta(1, 2, Score())
+ subject.storeTurnAndMeta(expectedTurnRequest, expectedTurnMeta, mockDone)
+ }
+
+ private fun whenStoringTurnSucceeds(id: Long) {
+ verify(mockTurnUc).exec(eq(expectedTurnRequest), storeOkCaptor.capture(), any())
+ storeOkCaptor.lastValue.invoke(StoreTurnResponse(id, expectedTurnRequest.turn))
+ }
+
+ private fun whenStoringTurnFails(err: Throwable) {
+ verify(mockTurnUc).exec(eq(expectedTurnRequest), any(), failCaptor.capture())
+ failCaptor.lastValue.invoke(err)
+ }
+
+ private fun thenTurnIsStored() {
+ verify(mockTurnUc).exec(eq(expectedTurnRequest), any(), any())
+ }
+
+ private fun whenLoadingGameAndStarting() {
+ subject.loadGameAndStart(req, done, fail)
+ }
+
+ private fun whenTeamsAreRetrieved() {
+ verify(mockTeamUc).exec(eq(RetrieveTeamsRequest(teamIds)), teamOkCaptor.capture(), any())
+ teamOkCaptor.firstValue.invoke(RetrieveTeamsResponse(teams))
+ }
+
+ private fun whenTeamsAreNotRetrieved() {
+ verify(mockTeamUc).exec(eq(RetrieveTeamsRequest(teamIds)), any(), failCaptor.capture())
+ failCaptor.firstValue.invoke(Throwable("unable to retrieve teams"))
+ }
+
+ private fun whenGameIsLoaded() {
+ whenever(mockGame.id).thenReturn(gameId)
+ verify(mockGameUc).start(eq(RetrieveGameRequest(gameId)), gameOkCaptor.capture(), any())
+ gameOkCaptor.firstValue.invoke(RetrieveGameResponse(mockGame))
+ }
+
+ private fun whenTurnsRetrieved() {
+ verify(mockTurnsUc).exec(eq(RetrieveTurnsRequest(gameId)), turnOkCaptor.capture(), any())
+ turnOkCaptor.firstValue.invoke(RetrieveTurnsResponse(mockTurns))
+ }
+
+ private fun whenGameIsNotLoaded() {
+ verify(mockGameUc).start(eq(RetrieveGameRequest(gameId)), any(), failCaptor.capture())
+ failCaptor.firstValue.invoke(Throwable("cant retrieve game"))
+ }
+
+ private fun whenGameIsFinished() {
+ givenMarkFinishRequest = MarkGameAsFinishedRequest(gameId)
+ subject.markGameAsFinished(givenMarkFinishRequest)
+ }
+ private fun whenUndoLastTurn() {
+ expectedUndoRequest = UndoTurnRequest(1)
+ subject.undoLastTurn(expectedUndoRequest, {}, {})
+ }
+
+ private fun thenGameIsStarted() {
+ verify(mockGame).start(2, teams)
+ }
+
+ private fun thenGameIsNotStarted() {
+ verify(mockGame, never()).start(2, teams)
+ }
+
+ private fun thenGameIsMarkedAsFinished() {
+ verify(mockMarkUc).exec(givenMarkFinishRequest)
+ }
+
+ private fun thenErrorIsLogged() {
+ verify(mockLogger).w(any())
+ }
+
+ private fun thenStatsAreStored() {
+ verify(mockStatsUc).exec(any(), any(), any())
+ }
+
+ private fun thenUndoUsecaseIsExecuted() {
+ verify(mockUndo).exec(eq(expectedUndoRequest), any(), any())
+ }
+
+}
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveGameUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveGameUsecaseTest.kt
similarity index 86%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveGameUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveGameUsecaseTest.kt
index c0494f2d..6f6e3c0d 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveGameUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveGameUsecaseTest.kt
@@ -1,10 +1,10 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.start
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.model.Game
import nl.entreco.domain.play.Arbiter
import nl.entreco.domain.repository.GameRepository
@@ -23,7 +23,7 @@ class RetrieveGameUsecaseTest {
@Mock private lateinit var mockGameRepository: GameRepository
@Mock private lateinit var mockArbiter: Arbiter
- @Mock private lateinit var mockOk: ((Game) -> Unit)
+ @Mock private lateinit var mockOk: ((RetrieveGameResponse) -> Unit)
@Mock private lateinit var mockErr: ((Throwable) -> Unit)
private lateinit var subject: RetrieveGameUsecase
@@ -67,7 +67,7 @@ class RetrieveGameUsecaseTest {
} else {
whenever(mockGameRepository.fetchBy(game.id)).thenReturn(game)
}
- subject.start(givenId, mockOk, mockErr)
+ subject.start(RetrieveGameRequest( givenId) , mockOk, mockErr)
}
private fun thenGameIsStarted() {
@@ -75,7 +75,7 @@ class RetrieveGameUsecaseTest {
}
private fun andOkIsReported() {
- verify(mockOk).invoke(game)
+ verify(mockOk).invoke(RetrieveGameResponse(game))
}
private fun thenErrIsReported() {
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTeamsResponseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTeamsResponseTest.kt
new file mode 100644
index 00000000..50cbc0dd
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTeamsResponseTest.kt
@@ -0,0 +1,45 @@
+package nl.entreco.domain.play.start
+
+import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.model.players.Team
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Test
+
+/**
+ * Created by entreco on 14/01/2018.
+ */
+class RetrieveTeamsResponseTest{
+ private val team1 = Team(arrayOf(Player("Guusje"), Player("Eva")))
+ private val team2 = Team(arrayOf(Player("Entreco")))
+ private val team3 = Team(emptyArray())
+ private val response1 = RetrieveTeamsResponse(arrayOf(team1))
+ private val response2 = RetrieveTeamsResponse(arrayOf(team1, team2))
+ private val response3 = RetrieveTeamsResponse(arrayOf(team1, team2, team3))
+
+ @Test
+ fun `should be equal`() {
+ assertEquals(response1, response1)
+ assertEquals(response1, RetrieveTeamsResponse(arrayOf(team1)))
+ }
+
+ @Test
+ fun `should not be equal`() {
+ assertNotEquals(response1, response2)
+ assertNotEquals(response1, response3)
+ assertNotEquals(response2, response3)
+ }
+
+ @Test
+ fun `should have same hashCode`() {
+ assertEquals(response1.hashCode(), response1.hashCode())
+ assertEquals(response1.hashCode(), RetrieveTeamsResponse(arrayOf(team1)).hashCode())
+ }
+
+ @Test
+ fun `should have differen hashcode`() {
+ assertNotEquals(response1.hashCode(), response2.hashCode())
+ assertNotEquals(response1.hashCode(), response3.hashCode())
+ assertNotEquals(response2.hashCode(), response3.hashCode())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveTeamsUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTeamsUsecaseTest.kt
similarity index 78%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveTeamsUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTeamsUsecaseTest.kt
index 11c1c780..3e7e981b 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveTeamsUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTeamsUsecaseTest.kt
@@ -1,11 +1,9 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.start
import com.nhaarman.mockito_kotlin.*
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.repository.TeamIdsString
import nl.entreco.domain.repository.PlayerRepository
import org.junit.Before
import org.junit.Test
@@ -19,10 +17,10 @@ class RetrieveTeamsUsecaseTest {
private val bg = TestBackground()
private val fg = TestForeground()
- private lateinit var teamIds: TeamIdsString
+ private lateinit var teamIds: String
- @Mock private lateinit var ok : (Array) -> Unit
- @Mock private lateinit var fail : (Throwable) -> Unit
+ @Mock private lateinit var ok: (RetrieveTeamsResponse) -> Unit
+ @Mock private lateinit var fail: (Throwable) -> Unit
@Mock private lateinit var mockPlayerRepository: PlayerRepository
@Mock private lateinit var mockPlayer: Player
@@ -51,12 +49,12 @@ class RetrieveTeamsUsecaseTest {
}
private fun givenPlayersWithIds(teams: String) {
- teamIds = TeamIdsString(teams)
+ teamIds = teams
whenever(mockPlayerRepository.fetchById(any())).thenReturn(mockPlayer)
}
private fun whenExecuting() {
- subject.exec(teamIds, ok, fail)
+ subject.exec(RetrieveTeamsRequest(teamIds), ok, fail)
}
private fun thenPlayersAreRetrieved(vararg ids: Long) {
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveTurnsUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTurnsUsecaseTest.kt
similarity index 70%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveTurnsUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTurnsUsecaseTest.kt
index 4c266635..50a34581 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/RetrieveTurnsUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/start/RetrieveTurnsUsecaseTest.kt
@@ -1,10 +1,10 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.start
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.model.Turn
import nl.entreco.domain.repository.TurnRepository
import org.junit.Test
@@ -24,14 +24,14 @@ class RetrieveTurnsUsecaseTest {
private lateinit var subject: RetrieveTurnsUsecase
private var givenGameId: Long = -1
- private var givenTurns: Array = emptyArray()
- @Mock private lateinit var mockOk: (Array) -> Unit
+ private var givenTurns: List> = emptyList()
+ @Mock private lateinit var mockOk: (RetrieveTurnsResponse) -> Unit
@Mock private lateinit var mockFail: (Throwable) -> Unit
@Test
fun `it should retrieve turns from database`() {
givenUsecase(66)
- givenStoredTurns(arrayOf(Turn(), Turn()))
+ givenStoredTurns(listOf(Pair(1L,Turn()), Pair(2L,Turn())))
whenRetrievingTurnsSucceeds()
thenOkIsExecuted()
}
@@ -39,7 +39,7 @@ class RetrieveTurnsUsecaseTest {
@Test
fun `it should report error when failing to retrieve turns from database`() {
givenUsecase(66)
- givenStoredTurns(arrayOf(Turn(), Turn()))
+ givenStoredTurns(listOf(Pair(1L,Turn()), Pair(2L,Turn())))
whenRetrievingTurnsFails(RuntimeException("Something wrong with db"))
thenFailIsExecuted()
}
@@ -49,22 +49,22 @@ class RetrieveTurnsUsecaseTest {
subject = RetrieveTurnsUsecase(mockTurnRepository, mockBg, mockFg)
}
- private fun givenStoredTurns(turns: Array) {
+ private fun givenStoredTurns(turns: List>) {
givenTurns = turns
}
private fun whenRetrievingTurnsSucceeds() {
- whenever(mockTurnRepository.fetchTurnsForGame(givenGameId)).thenReturn(givenTurns.toList())
- subject.exec(givenGameId, mockOk, mockFail)
+ whenever(mockTurnRepository.fetchTurnsForGame(givenGameId)).thenReturn(givenTurns)
+ subject.exec(RetrieveTurnsRequest(givenGameId), mockOk, mockFail)
}
private fun whenRetrievingTurnsFails(err: Throwable) {
whenever(mockTurnRepository.fetchTurnsForGame(givenGameId)).thenThrow(err)
- subject.exec(givenGameId, mockOk, mockFail)
+ subject.exec(RetrieveTurnsRequest(givenGameId), mockOk, mockFail)
}
private fun thenOkIsExecuted() {
- verify(mockOk).invoke(givenTurns)
+ verify(mockOk).invoke(RetrieveTurnsResponse(givenTurns))
}
private fun thenFailIsExecuted() {
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/FetchGameStatUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/FetchGameStatUsecaseTest.kt
new file mode 100644
index 00000000..bda52bad
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/FetchGameStatUsecaseTest.kt
@@ -0,0 +1,86 @@
+package nl.entreco.domain.play.stats
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
+import nl.entreco.domain.model.Stat
+import nl.entreco.domain.repository.StatRepository
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 24/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class FetchGameStatUsecaseTest {
+
+ @Mock private lateinit var mockStatRepository: StatRepository
+ @Mock private lateinit var done: (FetchGameStatResponse) -> Unit
+ @Mock private lateinit var fail: (Throwable) -> Unit
+ @Mock private lateinit var mockStat: Stat
+ private val bg = TestBackground()
+ private val fg = TestForeground()
+ private lateinit var subject: FetchGameStatUsecase
+
+ private val givenTurnId: Long = 8888
+ private val givenMetaId: Long = 9999
+
+ @Test
+ fun `it should fetch Stats from Repository`() {
+ givenSubject()
+ whenFetchingStats()
+ thenStatsAreFetched()
+ }
+
+ @Test
+ fun `it should report result when fetching succeeds`() {
+ givenSubject()
+ whenFetchingStatsSucceeds()
+ thenDoneIsInvoked()
+ }
+
+ @Test
+ fun `it should report failed when fetching fails`() {
+ givenSubject()
+ whenFetchingStatsFails(RuntimeException("do'h"))
+ thenFailIsInvoked()
+ }
+
+ private fun givenSubject() {
+ subject = FetchGameStatUsecase(mockStatRepository, bg, fg)
+ }
+
+ private fun whenFetchingStats() {
+ val req = FetchGameStatRequest(givenTurnId, givenMetaId)
+ subject.exec(req, done, fail)
+ }
+
+ private fun whenFetchingStatsSucceeds() {
+ whenever(mockStatRepository.fetchStat(givenTurnId, givenMetaId)).thenReturn(mockStat)
+ val req = FetchGameStatRequest(givenTurnId, givenMetaId)
+ subject.exec(req, done, fail)
+ }
+
+ private fun whenFetchingStatsFails(err: Throwable) {
+ whenever(mockStatRepository.fetchStat(givenTurnId, givenMetaId)).thenThrow(err)
+ val req = FetchGameStatRequest(givenTurnId, givenMetaId)
+ subject.exec(req, done, fail)
+ }
+
+ private fun thenStatsAreFetched() {
+ verify(mockStatRepository).fetchStat(givenTurnId, givenMetaId)
+ }
+
+ private fun thenDoneIsInvoked() {
+ verify(done).invoke(any())
+ }
+
+ private fun thenFailIsInvoked() {
+ verify(fail).invoke(any())
+ }
+
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/FetchGameStatsUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/FetchGameStatsUsecaseTest.kt
new file mode 100644
index 00000000..cc993c25
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/FetchGameStatsUsecaseTest.kt
@@ -0,0 +1,79 @@
+package nl.entreco.domain.play.stats
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
+import nl.entreco.domain.repository.StatRepository
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 24/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class FetchGameStatsUsecaseTest{
+ @Mock private lateinit var mockStatRepository: StatRepository
+ @Mock private lateinit var done: (FetchGameStatsResponse)->Unit
+ @Mock private lateinit var fail: (Throwable)->Unit
+ private val bg = TestBackground()
+ private val fg = TestForeground()
+ private lateinit var subject: FetchGameStatsUsecase
+
+ private val givenGameId : Long = 8888
+
+ @Test
+ fun `it should fetch Stats from Repository`() {
+ givenSubject()
+ whenFetchingStats()
+ thenStatsAreFetched()
+ }
+ @Test
+ fun `it should report result when fetching succeeds`() {
+ givenSubject()
+ whenFetchingStatsSucceeds()
+ thenDoneIsInvoked()
+ }
+ @Test
+ fun `it should report failed when fetching fails`() {
+ givenSubject()
+ whenFetchingStatsFails(RuntimeException("do'h"))
+ thenFailIsInvoked()
+ }
+
+ private fun givenSubject() {
+ subject = FetchGameStatsUsecase(mockStatRepository, bg, fg)
+ }
+
+ private fun whenFetchingStats() {
+ val req = FetchGameStatsRequest(givenGameId, "")
+ subject.exec(req, done, fail)
+ }
+
+ private fun whenFetchingStatsSucceeds() {
+ whenever(mockStatRepository.fetchAllForGame(givenGameId)).thenReturn(emptyMap())
+ val req = FetchGameStatsRequest(givenGameId, "")
+ subject.exec(req, done, fail)
+ }
+
+ private fun whenFetchingStatsFails(err: Throwable) {
+ whenever(mockStatRepository.fetchAllForGame(givenGameId)).thenThrow(err)
+ val req = FetchGameStatsRequest(givenGameId, "")
+ subject.exec(req, done, fail)
+ }
+
+ private fun thenStatsAreFetched(){
+ verify(mockStatRepository).fetchAllForGame(givenGameId)
+ }
+
+ private fun thenDoneIsInvoked(){
+ verify(done).invoke(any())
+ }
+
+ private fun thenFailIsInvoked(){
+ verify(fail).invoke(any())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/StoreMetaUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/StoreMetaUsecaseTest.kt
new file mode 100644
index 00000000..71d470a5
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/StoreMetaUsecaseTest.kt
@@ -0,0 +1,84 @@
+package nl.entreco.domain.play.stats
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.eq
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
+import nl.entreco.domain.model.Score
+import nl.entreco.domain.model.Turn
+import nl.entreco.domain.model.TurnMeta
+import nl.entreco.domain.play.ScoreEstimator
+import nl.entreco.domain.repository.MetaRepository
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 22/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class StoreMetaUsecaseTest {
+
+ @Mock private lateinit var mockMetaRepo: MetaRepository
+ @Mock private lateinit var mockDone: (Long, Long)->Unit
+ @Mock private lateinit var mockFail: (Throwable)->Unit
+ private val bg = TestBackground()
+ private val fg = TestForeground()
+ private val givenScoreEstimator = ScoreEstimator()
+ private lateinit var subject: StoreMetaUsecase
+ private lateinit var givenMeta: TurnMeta
+ private lateinit var givenRequest: StoreMetaRequest
+ private var givenTurnId: Long = -1
+ private var givenMetaId: Long = -1
+
+ @Test
+ fun `it should notify done, when usecase succeeds`() {
+ givenSubject()
+ givenMeta()
+ whenExecutingSucceeds()
+ thenDoneIsCalled()
+ }
+
+ @Test
+ fun `it should notify fail, when usecase fails`() {
+ givenSubject()
+ givenMeta()
+ whenExecutingFails()
+ thenFailIsCalled()
+ }
+
+ private fun givenSubject() {
+ subject = StoreMetaUsecase(mockMetaRepo, givenScoreEstimator, bg, fg)
+ }
+
+ private fun givenMeta(){
+ givenTurnId = 5
+ givenMetaId = 8
+ givenMeta = TurnMeta(3, 4, Score(), true, false)
+ givenRequest = StoreMetaRequest(givenTurnId,2, Turn(), givenMeta)
+ }
+
+ private fun whenExecutingSucceeds(){
+ whenever(mockMetaRepo.create(any(), any(), any(), any())).thenReturn(givenMetaId)
+ subject.exec(givenRequest, mockDone, mockFail)
+ verify(mockMetaRepo).create(eq(givenTurnId), eq(2), eq(givenMeta), any())
+ }
+
+ private fun whenExecutingFails(){
+ whenever(mockMetaRepo.create(any(), any(), any(), any())).thenThrow(RuntimeException("oh no, more lemmings"))
+ subject.exec(givenRequest, mockDone, mockFail)
+ verify(mockMetaRepo).create(eq(givenTurnId), eq(2), eq(givenMeta), any())
+ }
+
+ private fun thenDoneIsCalled() {
+ verify(mockDone).invoke(givenTurnId, givenMetaId)
+ }
+
+ private fun thenFailIsCalled() {
+ verify(mockFail).invoke(any())
+ }
+
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/StoreTurnUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/StoreTurnUsecaseTest.kt
similarity index 67%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/StoreTurnUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/StoreTurnUsecaseTest.kt
index 9f0dcfb7..3cfd9297 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/StoreTurnUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/StoreTurnUsecaseTest.kt
@@ -1,15 +1,14 @@
-package nl.entreco.domain.play.usecase
+package nl.entreco.domain.play.stats
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.executors.Background
-import nl.entreco.domain.executors.Foreground
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
+import nl.entreco.domain.common.executors.Background
+import nl.entreco.domain.common.executors.Foreground
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.model.Dart
import nl.entreco.domain.model.Turn
-import nl.entreco.domain.repository.StoreTurnRequest
import nl.entreco.domain.repository.TurnRepository
import org.junit.Before
import org.junit.Test
@@ -24,10 +23,13 @@ class StoreTurnUsecaseTest {
@Mock private lateinit var mockTurnRepository: TurnRepository
@Mock private lateinit var mockBg: Background
@Mock private lateinit var mockFg: Foreground
+ @Mock private lateinit var done: (StoreTurnResponse)->Unit
+ @Mock private lateinit var fail: (Throwable)->Unit
private val bg = TestBackground()
private val fg = TestForeground()
private lateinit var subject: StoreTurnUsecase
+ private var givenPlayerId : Long = -1
private var givenGameId : Long = -1
private lateinit var givenTurn : Turn
private lateinit var givenStoreRequest : StoreTurnRequest
@@ -40,7 +42,7 @@ class StoreTurnUsecaseTest {
@Test
fun `it should store turns using Repository`() {
givenViewModel(true)
- givenGameIdAndTurn(22, Turn())
+ givenGameIdAndTurn(66,22, Turn())
whenStoringTurn()
thenTurnIsStored()
}
@@ -49,7 +51,7 @@ class StoreTurnUsecaseTest {
@Test
fun `it should store turns even when throwing`() {
givenViewModel(true)
- givenGameIdAndTurn(22, Turn())
+ givenGameIdAndTurn(44,22, Turn())
whenStoringTurnThrows(RuntimeException("oops"))
thenExceptionIsHandled()
}
@@ -57,7 +59,7 @@ class StoreTurnUsecaseTest {
@Test
fun `it should store turns on background`() {
givenViewModel(false)
- givenGameIdAndTurn(88, Turn(Dart.SINGLE_1))
+ givenGameIdAndTurn(18, 88, Turn(Dart.SINGLE_1))
whenStoringTurn()
thenBackgroundThreadIsUsed()
}
@@ -70,23 +72,24 @@ class StoreTurnUsecaseTest {
}
}
- private fun givenGameIdAndTurn(gameId: Long, turn: Turn) {
+ private fun givenGameIdAndTurn(playerId: Long, gameId: Long, turn: Turn) {
+ givenPlayerId = playerId
givenGameId = gameId
givenTurn = turn
- givenStoreRequest = StoreTurnRequest(gameId , turn)
+ givenStoreRequest = StoreTurnRequest(givenPlayerId, gameId, turn)
}
private fun whenStoringTurn() {
- subject.exec(givenStoreRequest)
+ subject.exec(givenStoreRequest, done, fail)
}
private fun whenStoringTurnThrows(err: Throwable) {
- whenever(mockTurnRepository.store(any(), any())).thenThrow(err)
- subject.exec(givenStoreRequest)
+ whenever(mockTurnRepository.store(any(), any(), any())).thenThrow(err)
+ subject.exec(givenStoreRequest, done, fail)
}
private fun thenTurnIsStored() {
- verify(mockTurnRepository).store(givenGameId, givenTurn)
+ verify(mockTurnRepository).store(givenGameId, givenPlayerId, givenTurn)
}
private fun thenExceptionIsHandled(){
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/UndoTurnUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/UndoTurnUsecaseTest.kt
new file mode 100644
index 00000000..21093f73
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/stats/UndoTurnUsecaseTest.kt
@@ -0,0 +1,133 @@
+package nl.entreco.domain.play.stats
+
+import com.nhaarman.mockito_kotlin.any
+import com.nhaarman.mockito_kotlin.verify
+import com.nhaarman.mockito_kotlin.whenever
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
+import nl.entreco.domain.repository.GameRepository
+import nl.entreco.domain.repository.MetaRepository
+import nl.entreco.domain.repository.TurnRepository
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.junit.MockitoJUnitRunner
+
+/**
+ * Created by entreco on 25/01/2018.
+ */
+@RunWith(MockitoJUnitRunner::class)
+class UndoTurnUsecaseTest {
+
+ @Mock private lateinit var mockTurnRepo: TurnRepository
+ @Mock private lateinit var mockMetaRepo: MetaRepository
+ @Mock private lateinit var mockGameRepo: GameRepository
+ @Mock private lateinit var mockDone: (UndoTurnResponse) -> Unit
+ @Mock private lateinit var mockFail: (Throwable) -> Unit
+ private val bg = TestBackground()
+ private val fg = TestForeground()
+ private lateinit var subject: UndoTurnUsecase
+ private lateinit var givenUndoRequest: UndoTurnRequest
+
+ @Before
+ fun setUp() {
+ givenSubject()
+ }
+
+ @Test
+ fun `it should 'revert game finished' when undoing`() {
+ givenUndoRequest(5)
+ whenExecutingUsecase()
+ thenGameIsUnFinished(5)
+ }
+
+ @Test
+ fun `it should 'delete last turn' when undoing`() {
+ givenUndoRequest(1006)
+ whenExecutingUsecase()
+ thenLastTurnIsDeleted(1006)
+ }
+
+ @Test
+ fun `it should 'delete last meta' when undoing`() {
+ givenUndoRequest(-1)
+ whenExecutingUsecase()
+ thenLastMetaIsDeleted(-1)
+ }
+
+ @Test
+ fun `it should notify done when ok`() {
+ givenUndoRequest(11)
+ whenExecutingUsecase()
+ thenDoneIsCalled()
+ }
+
+ @Test
+ fun `it should notify fail when game fails`() {
+ givenUndoRequest(66)
+ whenUnfinishingFails(RuntimeException("unable to delete game"))
+ thenFailIsCalled()
+ }
+
+ @Test
+ fun `it should notify fail when turn fails`() {
+ givenUndoRequest(66)
+ whenUndoTurnFails(RuntimeException("unable to delete turns"))
+ thenFailIsCalled()
+ }
+
+ @Test
+ fun `it should notify fail when meta fails`() {
+ givenUndoRequest(66)
+ whenUndoMetaFails(RuntimeException("unable to delete meta"))
+ thenFailIsCalled()
+ }
+
+ private fun givenSubject() {
+ subject = UndoTurnUsecase(mockTurnRepo, mockMetaRepo, mockGameRepo, bg, fg)
+ }
+
+ private fun givenUndoRequest(gameId: Long) {
+ givenUndoRequest = UndoTurnRequest(gameId)
+ }
+
+ private fun whenExecutingUsecase() {
+ subject.exec(givenUndoRequest, mockDone, mockFail)
+ }
+
+ private fun whenUnfinishingFails(err: Throwable) {
+ whenever(mockGameRepo.undoFinish(any())).thenThrow(err)
+ subject.exec(givenUndoRequest, mockDone, mockFail)
+ }
+
+ private fun whenUndoTurnFails(err: Throwable) {
+ whenever(mockTurnRepo.undo(any())).thenThrow(err)
+ subject.exec(givenUndoRequest, mockDone, mockFail)
+ }
+
+ private fun whenUndoMetaFails(err: Throwable) {
+ whenever(mockMetaRepo.undo(any())).thenThrow(err)
+ subject.exec(givenUndoRequest, mockDone, mockFail)
+ }
+
+ private fun thenGameIsUnFinished(expected: Long) {
+ verify(mockGameRepo).undoFinish(expected)
+ }
+
+ private fun thenLastTurnIsDeleted(expected: Long) {
+ verify(mockTurnRepo).undo(expected)
+ }
+
+ private fun thenLastMetaIsDeleted(expected: Long) {
+ verify(mockMetaRepo).undo(expected)
+ }
+
+ private fun thenDoneIsCalled() {
+ verify(mockDone).invoke(any())
+ }
+
+ private fun thenFailIsCalled() {
+ verify(mockFail).invoke(any())
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/Play01UsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/Play01UsecaseTest.kt
deleted file mode 100644
index 406e12e3..00000000
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/play/usecase/Play01UsecaseTest.kt
+++ /dev/null
@@ -1,129 +0,0 @@
-package nl.entreco.domain.play.usecase
-
-import com.nhaarman.mockito_kotlin.*
-import nl.entreco.domain.model.Dart
-import nl.entreco.domain.model.Game
-import nl.entreco.domain.model.Turn
-import nl.entreco.domain.model.players.Player
-import nl.entreco.domain.model.players.Team
-import nl.entreco.domain.repository.CreateGameRequest
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.StoreTurnRequest
-import nl.entreco.domain.repository.TeamIdsString
-import org.junit.Before
-import org.junit.Test
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-
-/**
- * Created by Entreco on 17/12/2017.
- */
-class Play01UsecaseTest {
-
- private val gameId: Long = 42
- private val teams = arrayOf(Team(arrayOf(Player("1"), Player("2"))), Team(arrayOf(Player("3"))), Team(arrayOf(Player("4"))))
- private val teamIds = TeamIdsString("1,2|3|4")
- private val settings = CreateGameRequest(1001, 2, 3, 10)
- private val req: RetrieveGameRequest = RetrieveGameRequest(gameId, teamIds, settings)
-
- private val teamOkCaptor = argumentCaptor<(Array) -> Unit>()
- private val gameOkCaptor = argumentCaptor<(Game) -> Unit>()
- private val turnOkCaptor = argumentCaptor<(Array) -> Unit>()
- private val failCaptor = argumentCaptor<(Throwable) -> Unit>()
-
- @Mock private lateinit var done: (Game, Array) -> Unit
- @Mock private lateinit var fail: (Throwable) -> Unit
- @Mock private lateinit var mockGameUc: RetrieveGameUsecase
- @Mock private lateinit var mockTurnsUc: RetrieveTurnsUsecase
- @Mock private lateinit var mockTeamUc: RetrieveTeamsUsecase
- @Mock private lateinit var mockStoreUc: StoreTurnUsecase
- @Mock private lateinit var mockGame: Game
- private val mockTurns = emptyArray()
- private lateinit var expectedTurnRequest: StoreTurnRequest
-
- private lateinit var subject: Play01Usecase
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- subject = Play01Usecase(mockGameUc, mockTurnsUc, mockTeamUc, mockStoreUc)
- }
-
- @Test
- fun loadGameAndStart() {
- whenLoadingGameAndStarting()
- whenTeamsAreRetrieved()
- whenGameIsLoaded()
- whenTurnsRetrieved()
- thenGameIsStarted()
- }
-
- @Test
- fun loadGameWithTeamErrors() {
- whenLoadingGameAndStarting()
- whenTeamsAreNotRetrieved()
- thenGameIsNotStarted()
- }
-
- @Test
- fun loadGameWithGameErrors() {
- whenLoadingGameAndStarting()
- whenTeamsAreRetrieved()
- whenGameIsNotLoaded()
- thenGameIsNotStarted()
- }
-
- @Test
- fun storeTurn() {
- whenStoringTurn(Turn(Dart.DOUBLE_1, Dart.DOUBLE_15))
- thenTurnIsStored()
- }
-
- private fun whenStoringTurn(turn: Turn) {
- expectedTurnRequest = StoreTurnRequest(gameId, turn)
- subject.storeTurn(expectedTurnRequest)
- }
-
- private fun thenTurnIsStored() {
- verify(mockStoreUc).exec(expectedTurnRequest)
- }
-
- private fun whenLoadingGameAndStarting() {
- subject.loadGameAndStart(req, done, fail)
- }
-
- private fun whenTeamsAreRetrieved() {
- verify(mockTeamUc).exec(eq(teamIds), teamOkCaptor.capture(), any())
- teamOkCaptor.firstValue.invoke(teams)
- }
-
- private fun whenTeamsAreNotRetrieved() {
- verify(mockTeamUc).exec(eq(teamIds), any(), failCaptor.capture())
- failCaptor.firstValue.invoke(Throwable("unable to retrieve teams"))
- }
-
- private fun whenGameIsLoaded() {
- whenever(mockGame.id).thenReturn(gameId)
- verify(mockGameUc).start(eq(gameId), gameOkCaptor.capture(), any())
- gameOkCaptor.firstValue.invoke(mockGame)
- }
-
- private fun whenTurnsRetrieved() {
- verify(mockTurnsUc).exec(eq(gameId), turnOkCaptor.capture(), any())
- turnOkCaptor.firstValue.invoke(mockTurns)
- }
-
- private fun whenGameIsNotLoaded() {
- verify(mockGameUc).start(eq(gameId), any(), failCaptor.capture())
- failCaptor.firstValue.invoke(Throwable("cant retrieve game"))
- }
-
- private fun thenGameIsStarted() {
- verify(mockGame).start(2, teams)
- }
-
- private fun thenGameIsNotStarted() {
- verify(mockGame, never()).start(2, teams)
- }
-
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestParcelableTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestParcelableTest.kt
index 38314e0e..d542592e 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestParcelableTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestParcelableTest.kt
@@ -1,8 +1,5 @@
package nl.entreco.domain.repository
-import org.junit.Assert.*
-import org.junit.runner.RunWith
-
/**
* Created by Entreco on 02/01/2018.
*/
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestTest.kt
index 82342ad8..f1e3be6f 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameRequestTest.kt
@@ -1,5 +1,6 @@
package nl.entreco.domain.repository
+import nl.entreco.domain.setup.game.CreateGameRequest
import org.junit.Assert.assertEquals
import org.junit.Test
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameResponseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameResponseTest.kt
new file mode 100644
index 00000000..cd775811
--- /dev/null
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/CreateGameResponseTest.kt
@@ -0,0 +1,22 @@
+package nl.entreco.domain.repository
+
+import nl.entreco.domain.setup.game.CreateGameResponse
+import org.junit.Assert.assertEquals
+import org.junit.Test
+
+/**
+ * Created by Entreco on 18/12/2017.
+ */
+class CreateGameResponseTest {
+
+ @Test
+ fun basic() {
+ val request = CreateGameResponse(22, "2,3|8", 0, 2, 3, 4)
+ assertEquals(22, request.gameId)
+ assertEquals("2,3|8", request.teamIds.toString())
+ assertEquals(0, request.startScore)
+ assertEquals(2, request.startIndex)
+ assertEquals(3, request.numLegs)
+ assertEquals(4, request.numSets)
+ }
+}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/RetrieveGameRequestTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/RetrieveGameRequestTest.kt
deleted file mode 100644
index 679d0a36..00000000
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/RetrieveGameRequestTest.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-package nl.entreco.domain.repository
-
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-/**
- * Created by Entreco on 18/12/2017.
- */
-class RetrieveGameRequestTest {
-
- @Test
- fun basic() {
- val request = RetrieveGameRequest(22, TeamIdsString("2,3|8"), CreateGameRequest(0, 2, 3, 4))
- assertEquals(22, request.gameId)
- assertEquals("2,3|8", request.teamIds.toString())
- assertEquals(0, request.create.startScore)
- assertEquals(2, request.create.startIndex)
- assertEquals(3, request.create.numLegs)
- assertEquals(4, request.create.numSets)
- }
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/TeamIdsStringTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/TeamIdsStringTest.kt
deleted file mode 100644
index 9e4e2a6e..00000000
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/repository/TeamIdsStringTest.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-package nl.entreco.domain.repository
-
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-/**
- * Created by Entreco on 17/12/2017.
- */
-class TeamIdsStringTest {
-
- @Test
- fun `it should return correct string representation`() {
- assertEquals("1,2|3", TeamIdsString("1,2|3").toString())
- }
-
-}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/settings/ScoreSettingsTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/settings/ScoreSettingsTest.kt
index 02859b52..1238420a 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/settings/ScoreSettingsTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/settings/ScoreSettingsTest.kt
@@ -1,10 +1,9 @@
package nl.entreco.domain.settings
import nl.entreco.domain.model.Score
+import org.junit.Assert.assertEquals
import org.junit.Test
-import org.junit.Assert.*
-
/**
* Created by Entreco on 18/12/2017.
*/
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/CreateGameUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/game/CreateGameUsecaseTest.kt
similarity index 74%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/CreateGameUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/game/CreateGameUsecaseTest.kt
index e748e974..e53da098 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/launch/usecase/CreateGameUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/game/CreateGameUsecaseTest.kt
@@ -1,15 +1,11 @@
-package nl.entreco.domain.launch.usecase
+package nl.entreco.domain.setup.game
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.verify
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
-import nl.entreco.domain.model.Game
-import nl.entreco.domain.repository.CreateGameRequest
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.repository.GameRepository
-import nl.entreco.domain.repository.RetrieveGameRequest
-import nl.entreco.domain.repository.TeamIdsString
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -24,15 +20,14 @@ import org.mockito.junit.MockitoJUnitRunner
class CreateGameUsecaseTest {
@Mock private lateinit var mockGameRepository: GameRepository
- @Mock private lateinit var mockGame: Game
- @Mock private lateinit var mockOk: (RetrieveGameRequest) -> Unit
+ @Mock private lateinit var mockOk: (CreateGameResponse) -> Unit
@Mock private lateinit var mockFail: (Throwable) -> Unit
private lateinit var subject: CreateGameUsecase
private var setup = CreateGameRequest(501, 0, 3, 2)
- private var teamString = TeamIdsString("a|b")
+ private var teamString = "a|b"
private var mockBg = TestBackground()
private var mockFg = TestForeground()
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/CreatePlayerUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/players/CreatePlayerUsecaseTest.kt
similarity index 83%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/CreatePlayerUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/players/CreatePlayerUsecaseTest.kt
index 8f76220b..a7451579 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/CreatePlayerUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/players/CreatePlayerUsecaseTest.kt
@@ -1,9 +1,8 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.players
import com.nhaarman.mockito_kotlin.*
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
-import nl.entreco.domain.model.players.Player
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.repository.PlayerRepository
import org.junit.Assert.assertEquals
import org.junit.Test
@@ -18,14 +17,14 @@ import org.mockito.junit.MockitoJUnitRunner
class CreatePlayerUsecaseTest {
@Mock private lateinit var mockRepo : PlayerRepository
- @Mock private lateinit var mockDone : (Player)->Unit
+ @Mock private lateinit var mockDone : (CreatePlayerResponse)->Unit
@Mock private lateinit var mockFail : (Throwable)->Unit
private val bg = TestBackground()
private val fg = TestForeground()
private val givenId : Long = 10
private lateinit var subject : CreatePlayerUsecase
private lateinit var givenRequest : CreatePlayerRequest
- private val okCaptor = argumentCaptor()
+ private val okCaptor = argumentCaptor()
@Test
fun `it should report Player when creating succeeds`() {
@@ -81,9 +80,9 @@ class CreatePlayerUsecaseTest {
private fun thenSuccessIsReported(){
verify(mockDone).invoke(okCaptor.capture())
- assertEquals(givenRequest.name.toLowerCase(), okCaptor.lastValue.name)
- assertEquals(givenRequest.double, okCaptor.lastValue.prefs.favoriteDouble)
- assertEquals(givenId, okCaptor.lastValue.id)
+ assertEquals(givenRequest.name.toLowerCase(), okCaptor.lastValue.player.name)
+ assertEquals(givenRequest.double, okCaptor.lastValue.player.prefs.favoriteDouble)
+ assertEquals(givenId, okCaptor.lastValue.player.id)
}
private fun thenErrorIsReported(){
@@ -91,7 +90,7 @@ class CreatePlayerUsecaseTest {
}
private fun andReturnedPlayerNameIs(expected: String) {
- assertEquals(expected, okCaptor.lastValue.name)
+ assertEquals(expected, okCaptor.lastValue.player.name)
}
}
\ No newline at end of file
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/FetchExistingPlayersUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/players/FetchExistingPlayersUsecaseTest.kt
similarity index 86%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/FetchExistingPlayersUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/players/FetchExistingPlayersUsecaseTest.kt
index 14a68325..cdf31783 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/FetchExistingPlayersUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/players/FetchExistingPlayersUsecaseTest.kt
@@ -1,13 +1,12 @@
-package nl.entreco.domain.setup
+package nl.entreco.domain.setup.players
import com.nhaarman.mockito_kotlin.argumentCaptor
import com.nhaarman.mockito_kotlin.verify
import com.nhaarman.mockito_kotlin.whenever
-import nl.entreco.domain.executors.TestBackground
-import nl.entreco.domain.executors.TestForeground
+import nl.entreco.domain.common.executors.TestBackground
+import nl.entreco.domain.common.executors.TestForeground
import nl.entreco.domain.model.players.Player
import nl.entreco.domain.repository.PlayerRepository
-import nl.entreco.domain.setup.usecase.FetchExistingPlayersUsecase
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
@@ -21,11 +20,11 @@ import org.mockito.junit.MockitoJUnitRunner
class FetchExistingPlayersUsecaseTest {
@Mock private lateinit var mockRepo: PlayerRepository
- @Mock private lateinit var mockDone: (List) -> Unit
+ @Mock private lateinit var mockDone: (FetchExistingPlayersResponse) -> Unit
@Mock private lateinit var mockFail: (Throwable) -> Unit
private val bg = TestBackground()
private val fg = TestForeground()
- private val playersCaptor = argumentCaptor>()
+ private val playersCaptor = argumentCaptor()
private lateinit var subject: FetchExistingPlayersUsecase
private lateinit var expectedPlayers: List
@@ -81,7 +80,7 @@ class FetchExistingPlayersUsecaseTest {
private fun thenDoneIsCalledWithPlayers(vararg names: String) {
verify(mockDone).invoke(playersCaptor.capture())
- val players: List = playersCaptor.lastValue.map { it.name }
+ val players: List = playersCaptor.lastValue.players.map { it.name }
names.forEach {
assertTrue(players.contains(it))
}
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/FetchPreferredSettingsUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/FetchPreferredSettingsUsecaseTest.kt
similarity index 98%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/FetchPreferredSettingsUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/FetchPreferredSettingsUsecaseTest.kt
index 67bab465..23f736cd 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/FetchPreferredSettingsUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/FetchPreferredSettingsUsecaseTest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
import android.database.sqlite.SQLiteDatabaseLockedException
import com.nhaarman.mockito_kotlin.argumentCaptor
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/FetchSettingsResponseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/FetchSettingsResponseTest.kt
similarity index 94%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/FetchSettingsResponseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/FetchSettingsResponseTest.kt
index b59eacfa..f6dda41b 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/FetchSettingsResponseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/FetchSettingsResponseTest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
import org.junit.Assert.assertEquals
import org.junit.Test
diff --git a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/StorePreferredSettingsUsecaseTest.kt b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/StorePreferredSettingsUsecaseTest.kt
similarity index 89%
rename from android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/StorePreferredSettingsUsecaseTest.kt
rename to android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/StorePreferredSettingsUsecaseTest.kt
index 68e7a12c..1aa7999b 100644
--- a/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/usecase/StorePreferredSettingsUsecaseTest.kt
+++ b/android/DartsScorecard/domain/src/test/java/nl/entreco/domain/setup/settings/StorePreferredSettingsUsecaseTest.kt
@@ -1,4 +1,4 @@
-package nl.entreco.domain.setup.usecase
+package nl.entreco.domain.setup.settings
import com.nhaarman.mockito_kotlin.verify
import nl.entreco.domain.repository.PreferenceRepository
@@ -14,7 +14,7 @@ import org.mockito.junit.MockitoJUnitRunner
class StorePreferredSettingsUsecaseTest{
@Mock private lateinit var mockPrefsRepo : PreferenceRepository
private lateinit var subject : StorePreferredSettingsUsecase
- private val givenRequest = StoreSettingsRequest(11,12,13,14,15)
+ private val givenRequest = StoreSettingsRequest(11, 12, 13, 14, 15)
@Test
fun `it should store settings in PreferenceRepo`() {
diff --git a/android/DartsScorecard/projectFilesBackup/.idea/workspace.xml b/android/DartsScorecard/projectFilesBackup/.idea/workspace.xml
new file mode 100644
index 00000000..aaf71767
--- /dev/null
+++ b/android/DartsScorecard/projectFilesBackup/.idea/workspace.xml
@@ -0,0 +1,5710 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ nl.entreco.dartsscorecard.play.score.*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ s
+ showApp
+ c
+ SETUP
+ compile
+ RE
+ RESULT_
+ RESULT_C
+ RESULT_CA
+ RESULT_CANC
+ RESULT_CANCE
+ RESULT_CANCELLED
+ RESULT_CANCELLE
+ RESULT_CANCELL
+ RESULT_CANCELE
+ RESULT_CANCELED
+ RESULT_CANCEL
+ RESULT_OK
+ special
+
+
+ PREF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AccessibilityLintAndroid
+
+
+ Android
+
+
+ CorrectnessLintAndroid
+
+
+ Error handlingJava
+
+
+ IconsUsabilityLintAndroid
+
+
+ Internationalization issues
+
+
+ Java
+
+
+ Java 8Java language level migration aidsJava
+
+
+ Java language level migration aidsJava
+
+
+ LintAndroid
+
+
+ Performance issuesJava
+
+
+ PerformanceLintAndroid
+
+
+ SecurityLintAndroid
+
+
+ UsabilityLintAndroid
+
+
+
+
+ Android
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1510605649092
+
+
+ 1510605649092
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerNavigator.kt
+ 12
+
+
+
+
+ file://$PROJECT_DIR$/app/src/main/java/nl/entreco/dartsscorecard/setup/edit/EditPlayerNavigator.kt
+ 17
+
+
+
+
+ file://$PROJECT_DIR$/domain/src/main/java/nl/entreco/domain/setup/players/CreatePlayerUsecase.kt
+ 26
+
+
+
+
+ file://$PROJECT_DIR$/app/src/test/java/nl/entreco/dartsscorecard/launch/LaunchViewModelTest.kt
+ 69
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/DartsScorecard/scripts/dependencies.gradle b/android/DartsScorecard/scripts/dependencies.gradle
index 350e10ec..b5e13743 100644
--- a/android/DartsScorecard/scripts/dependencies.gradle
+++ b/android/DartsScorecard/scripts/dependencies.gradle
@@ -34,11 +34,11 @@ ext.versionName = { ->
ext {
- kotlinVersion = '1.2.10'
+ kotlinVersion = '1.2.21'
gradleVersion = '3.0.1'
gmsVersion = '3.1.1'
dexCountVersion = '0.8.2'
- detektVersion = '1.0.0.RC6-1'
+ detektVersion = '1.0.0.RC6-2'
jacocoCoverageVersion = '0.4.0'
coverallsVersion = '2.8.2'
diff --git a/design/gymnast.svg b/design/gymnast.svg
new file mode 100644
index 00000000..6bf8201a
--- /dev/null
+++ b/design/gymnast.svg
@@ -0,0 +1,130 @@
+
+
+
diff --git a/design/people.svg b/design/people.svg
new file mode 100644
index 00000000..b1f6544c
--- /dev/null
+++ b/design/people.svg
@@ -0,0 +1,75 @@
+
+
+
diff --git a/design/player1.svg b/design/player1.svg
index 7098347c..d9da0cb6 100644
--- a/design/player1.svg
+++ b/design/player1.svg
@@ -1,102 +1,44 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/design/player2.svg b/design/player2.svg
index ef34fa0e..52413d59 100644
--- a/design/player2.svg
+++ b/design/player2.svg
@@ -1,151 +1,42 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/design/referee (1).svg b/design/referee (1).svg
new file mode 100644
index 00000000..2941da94
--- /dev/null
+++ b/design/referee (1).svg
@@ -0,0 +1,99 @@
+
+
+
diff --git a/design/referee.svg b/design/referee.svg
new file mode 100644
index 00000000..ff0d63ba
--- /dev/null
+++ b/design/referee.svg
@@ -0,0 +1,102 @@
+
+
+
diff --git a/dsc_db.db b/dsc_db.db
new file mode 100644
index 00000000..5e6c7f82
Binary files /dev/null and b/dsc_db.db differ
diff --git a/release/0.0.7/mapping.txt b/release/0.0.7/mapping.txt
deleted file mode 100644
index 001ade29..00000000
--- a/release/0.0.7/mapping.txt
+++ /dev/null
@@ -1,21925 +0,0 @@
-android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:
- android.arch.core.executor.ArchTaskExecutor sInstance -> a
- android.arch.core.executor.TaskExecutor mDelegate -> b
- android.arch.core.executor.TaskExecutor mDefaultTaskExecutor -> c
- java.util.concurrent.Executor sMainThreadExecutor -> d
- java.util.concurrent.Executor sIOThreadExecutor -> e
- void () ->
- android.arch.core.executor.ArchTaskExecutor getInstance() -> a
- void executeOnDiskIO(java.lang.Runnable) -> a
- void postToMainThread(java.lang.Runnable) -> b
- boolean isMainThread() -> b
- void () ->
-android.arch.core.executor.ArchTaskExecutor$1 -> android.arch.a.a.a$1:
- void () ->
- void execute(java.lang.Runnable) -> execute
-android.arch.core.executor.ArchTaskExecutor$2 -> android.arch.a.a.a$2:
- void () ->
- void execute(java.lang.Runnable) -> execute
-android.arch.core.executor.DefaultTaskExecutor -> android.arch.a.a.b:
- java.lang.Object mLock -> a
- java.util.concurrent.ExecutorService mDiskIO -> b
- android.os.Handler mMainHandler -> c
- void () ->
- void executeOnDiskIO(java.lang.Runnable) -> a
- void postToMainThread(java.lang.Runnable) -> b
- boolean isMainThread() -> b
-android.arch.core.executor.TaskExecutor -> android.arch.a.a.c:
- void () ->
- void executeOnDiskIO(java.lang.Runnable) -> a
- void postToMainThread(java.lang.Runnable) -> b
- boolean isMainThread() -> b
-android.arch.core.internal.FastSafeIterableMap -> android.arch.a.b.a:
- java.util.HashMap mHashMap -> a
- void () ->
- android.arch.core.internal.SafeIterableMap$Entry get(java.lang.Object) -> a
- java.lang.Object remove(java.lang.Object) -> b
- boolean contains(java.lang.Object) -> c
-android.arch.core.internal.SafeIterableMap -> android.arch.a.b.b:
- android.arch.core.internal.SafeIterableMap$Entry mStart -> a
- android.arch.core.internal.SafeIterableMap$Entry mEnd -> b
- java.util.WeakHashMap mIterators -> c
- int mSize -> d
- void () ->
- android.arch.core.internal.SafeIterableMap$Entry get(java.lang.Object) -> a
- java.lang.Object remove(java.lang.Object) -> b
- int size() -> a
- java.util.Iterator iterator() -> iterator
- java.util.Iterator descendingIterator() -> b
- android.arch.core.internal.SafeIterableMap$IteratorWithAdditions iteratorWithAdditions() -> c
- java.util.Map$Entry eldest() -> d
- java.util.Map$Entry newest() -> e
- boolean equals(java.lang.Object) -> equals
- java.lang.String toString() -> toString
- android.arch.core.internal.SafeIterableMap$Entry access$100(android.arch.core.internal.SafeIterableMap) -> a
-android.arch.core.internal.SafeIterableMap$1 -> android.arch.a.b.b$1:
-android.arch.core.internal.SafeIterableMap$AscendingIterator -> android.arch.a.b.b$a:
- void (android.arch.core.internal.SafeIterableMap$Entry,android.arch.core.internal.SafeIterableMap$Entry) ->
- android.arch.core.internal.SafeIterableMap$Entry forward(android.arch.core.internal.SafeIterableMap$Entry) -> a
- android.arch.core.internal.SafeIterableMap$Entry backward(android.arch.core.internal.SafeIterableMap$Entry) -> b
-android.arch.core.internal.SafeIterableMap$DescendingIterator -> android.arch.a.b.b$b:
- void (android.arch.core.internal.SafeIterableMap$Entry,android.arch.core.internal.SafeIterableMap$Entry) ->
- android.arch.core.internal.SafeIterableMap$Entry forward(android.arch.core.internal.SafeIterableMap$Entry) -> a
- android.arch.core.internal.SafeIterableMap$Entry backward(android.arch.core.internal.SafeIterableMap$Entry) -> b
-android.arch.core.internal.SafeIterableMap$Entry -> android.arch.a.b.b$c:
- java.lang.Object mKey -> a
- java.lang.Object mValue -> b
- android.arch.core.internal.SafeIterableMap$Entry mNext -> c
- android.arch.core.internal.SafeIterableMap$Entry mPrevious -> d
- java.lang.Object getKey() -> getKey
- java.lang.Object getValue() -> getValue
- java.lang.Object setValue(java.lang.Object) -> setValue
- java.lang.String toString() -> toString
- boolean equals(java.lang.Object) -> equals
-android.arch.core.internal.SafeIterableMap$IteratorWithAdditions -> android.arch.a.b.b$d:
- android.arch.core.internal.SafeIterableMap$Entry mCurrent -> b
- boolean mBeforeStart -> c
- android.arch.core.internal.SafeIterableMap this$0 -> a
- void (android.arch.core.internal.SafeIterableMap) ->
- void supportRemove(android.arch.core.internal.SafeIterableMap$Entry) -> a_
- boolean hasNext() -> hasNext
- java.util.Map$Entry next() -> a
- java.lang.Object next() -> next
- void (android.arch.core.internal.SafeIterableMap,android.arch.core.internal.SafeIterableMap$1) ->
-android.arch.core.internal.SafeIterableMap$ListIterator -> android.arch.a.b.b$e:
- android.arch.core.internal.SafeIterableMap$Entry mExpectedEnd -> a
- android.arch.core.internal.SafeIterableMap$Entry mNext -> b
- void (android.arch.core.internal.SafeIterableMap$Entry,android.arch.core.internal.SafeIterableMap$Entry) ->
- boolean hasNext() -> hasNext
- void supportRemove(android.arch.core.internal.SafeIterableMap$Entry) -> a_
- android.arch.core.internal.SafeIterableMap$Entry nextNode() -> b
- java.util.Map$Entry next() -> a
- android.arch.core.internal.SafeIterableMap$Entry forward(android.arch.core.internal.SafeIterableMap$Entry) -> a
- android.arch.core.internal.SafeIterableMap$Entry backward(android.arch.core.internal.SafeIterableMap$Entry) -> b
- java.lang.Object next() -> next
-android.arch.core.internal.SafeIterableMap$SupportRemove -> android.arch.a.b.b$f:
- void supportRemove(android.arch.core.internal.SafeIterableMap$Entry) -> a_
-android.arch.lifecycle.AndroidViewModel -> android.arch.lifecycle.AndroidViewModel:
-android.arch.lifecycle.ClassesInfoCache -> android.arch.lifecycle.a:
- android.arch.lifecycle.ClassesInfoCache sInstance -> a
- java.util.Map mCallbackMap -> b
- java.util.Map mHasLifecycleMethods -> c
- void () ->
- void () ->
-android.arch.lifecycle.ClassesInfoCache$CallbackInfo -> android.arch.lifecycle.a$a:
- java.util.Map mEventToHandlers -> a
- void invokeCallbacks(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event,java.lang.Object) -> a
- void invokeMethodsForEvent(java.util.List,android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event,java.lang.Object) -> a
-android.arch.lifecycle.ClassesInfoCache$MethodReference -> android.arch.lifecycle.a$b:
- int mCallType -> a
- java.lang.reflect.Method mMethod -> b
- void invokeCallback(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event,java.lang.Object) -> a
- boolean equals(java.lang.Object) -> equals
- int hashCode() -> hashCode
-android.arch.lifecycle.CompositeGeneratedAdaptersObserver -> android.arch.lifecycle.CompositeGeneratedAdaptersObserver:
- android.arch.lifecycle.GeneratedAdapter[] mGeneratedAdapters -> a
- void onStateChanged(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event) -> a
-android.arch.lifecycle.EmptyActivityLifecycleCallbacks -> android.arch.lifecycle.b:
- void () ->
- void onActivityCreated(android.app.Activity,android.os.Bundle) -> onActivityCreated
- void onActivityStarted(android.app.Activity) -> onActivityStarted
- void onActivityResumed(android.app.Activity) -> onActivityResumed
- void onActivityPaused(android.app.Activity) -> onActivityPaused
- void onActivityStopped(android.app.Activity) -> onActivityStopped
- void onActivitySaveInstanceState(android.app.Activity,android.os.Bundle) -> onActivitySaveInstanceState
- void onActivityDestroyed(android.app.Activity) -> onActivityDestroyed
-android.arch.lifecycle.FullLifecycleObserver -> android.arch.lifecycle.FullLifecycleObserver:
- void onCreate(android.arch.lifecycle.LifecycleOwner) -> a
- void onStart(android.arch.lifecycle.LifecycleOwner) -> b
- void onResume(android.arch.lifecycle.LifecycleOwner) -> c
- void onPause(android.arch.lifecycle.LifecycleOwner) -> d
- void onStop(android.arch.lifecycle.LifecycleOwner) -> e
- void onDestroy(android.arch.lifecycle.LifecycleOwner) -> f
-android.arch.lifecycle.FullLifecycleObserverAdapter -> android.arch.lifecycle.FullLifecycleObserverAdapter:
- android.arch.lifecycle.FullLifecycleObserver mObserver -> a
- void onStateChanged(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event) -> a
-android.arch.lifecycle.FullLifecycleObserverAdapter$1 -> android.arch.lifecycle.FullLifecycleObserverAdapter$1:
- int[] $SwitchMap$android$arch$lifecycle$Lifecycle$Event -> a
- void () ->
-android.arch.lifecycle.GeneratedAdapter -> android.arch.lifecycle.c:
- void callMethods(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event,boolean,android.arch.lifecycle.MethodCallsLogger) -> a
-android.arch.lifecycle.GenericLifecycleObserver -> android.arch.lifecycle.GenericLifecycleObserver:
- void onStateChanged(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event) -> a
-android.arch.lifecycle.HolderFragment -> android.arch.lifecycle.d:
- android.arch.lifecycle.HolderFragment$HolderFragmentManager sHolderFragmentManager -> V
- android.arch.lifecycle.ViewModelStore mViewModelStore -> W
- void () ->
- void onCreate(android.os.Bundle) -> a
- void onSaveInstanceState(android.os.Bundle) -> b
- void onDestroy() -> a
- android.arch.lifecycle.ViewModelStore getViewModelStore() -> b
- android.arch.lifecycle.HolderFragment holderFragmentFor(android.support.v4.app.FragmentActivity) -> a
- void () ->
-android.arch.lifecycle.HolderFragment$HolderFragmentManager -> android.arch.lifecycle.d$a:
- java.util.Map mNotCommittedActivityHolders -> a
- java.util.Map mNotCommittedFragmentHolders -> b
- android.app.Application$ActivityLifecycleCallbacks mActivityCallbacks -> c
- boolean mActivityCallbacksIsAdded -> d
- android.support.v4.app.FragmentManager$FragmentLifecycleCallbacks mParentDestroyedCallback -> e
- void () ->
- void holderFragmentCreated(android.support.v4.app.Fragment) -> a
- android.arch.lifecycle.HolderFragment findHolderFragment(android.support.v4.app.FragmentManager) -> a
- android.arch.lifecycle.HolderFragment createHolderFragment(android.support.v4.app.FragmentManager) -> b
- android.arch.lifecycle.HolderFragment holderFragmentFor(android.support.v4.app.FragmentActivity) -> a
- java.util.Map access$000(android.arch.lifecycle.HolderFragment$HolderFragmentManager) -> a
- java.util.Map access$100(android.arch.lifecycle.HolderFragment$HolderFragmentManager) -> b
-android.arch.lifecycle.HolderFragment$HolderFragmentManager$1 -> android.arch.lifecycle.d$a$1:
- android.arch.lifecycle.HolderFragment$HolderFragmentManager this$0 -> a
- void (android.arch.lifecycle.HolderFragment$HolderFragmentManager) ->
- void onActivityDestroyed(android.app.Activity) -> onActivityDestroyed
-android.arch.lifecycle.HolderFragment$HolderFragmentManager$2 -> android.arch.lifecycle.d$a$2:
- android.arch.lifecycle.HolderFragment$HolderFragmentManager this$0 -> a
- void (android.arch.lifecycle.HolderFragment$HolderFragmentManager) ->
- void onFragmentDestroyed(android.support.v4.app.FragmentManager,android.support.v4.app.Fragment) -> a
-android.arch.lifecycle.Lifecycle -> android.arch.lifecycle.e:
- void () ->
- void removeObserver(android.arch.lifecycle.LifecycleObserver) -> a
- android.arch.lifecycle.Lifecycle$State getCurrentState() -> a
-android.arch.lifecycle.Lifecycle$Event -> android.arch.lifecycle.e$a:
- android.arch.lifecycle.Lifecycle$Event ON_CREATE -> ON_CREATE
- android.arch.lifecycle.Lifecycle$Event ON_START -> ON_START
- android.arch.lifecycle.Lifecycle$Event ON_RESUME -> ON_RESUME
- android.arch.lifecycle.Lifecycle$Event ON_PAUSE -> ON_PAUSE
- android.arch.lifecycle.Lifecycle$Event ON_STOP -> ON_STOP
- android.arch.lifecycle.Lifecycle$Event ON_DESTROY -> ON_DESTROY
- android.arch.lifecycle.Lifecycle$Event ON_ANY -> ON_ANY
- android.arch.lifecycle.Lifecycle$Event[] $VALUES -> $VALUES
- android.arch.lifecycle.Lifecycle$Event[] values() -> values
- android.arch.lifecycle.Lifecycle$Event valueOf(java.lang.String) -> valueOf
- void (java.lang.String,int) ->
- void () ->
-android.arch.lifecycle.Lifecycle$State -> android.arch.lifecycle.e$b:
- android.arch.lifecycle.Lifecycle$State DESTROYED -> a
- android.arch.lifecycle.Lifecycle$State INITIALIZED -> b
- android.arch.lifecycle.Lifecycle$State CREATED -> c
- android.arch.lifecycle.Lifecycle$State STARTED -> d
- android.arch.lifecycle.Lifecycle$State RESUMED -> e
- android.arch.lifecycle.Lifecycle$State[] $VALUES -> f
- android.arch.lifecycle.Lifecycle$State[] values() -> values
- android.arch.lifecycle.Lifecycle$State valueOf(java.lang.String) -> valueOf
- void (java.lang.String,int) ->
- boolean isAtLeast(android.arch.lifecycle.Lifecycle$State) -> a
- void () ->
-android.arch.lifecycle.LifecycleDispatcher -> android.arch.lifecycle.f:
- java.util.concurrent.atomic.AtomicBoolean sInitialized -> a
- void init(android.content.Context) -> a
- void markState(android.support.v4.app.FragmentManager,android.arch.lifecycle.Lifecycle$State) -> a
- void markStateIn(java.lang.Object,android.arch.lifecycle.Lifecycle$State) -> a
- void markState(android.support.v4.app.FragmentActivity,android.arch.lifecycle.Lifecycle$State) -> b
- void dispatchIfLifecycleOwner(android.support.v4.app.Fragment,android.arch.lifecycle.Lifecycle$Event) -> b
- void access$000(android.support.v4.app.FragmentActivity,android.arch.lifecycle.Lifecycle$State) -> a
- void access$100(android.support.v4.app.Fragment,android.arch.lifecycle.Lifecycle$Event) -> a
- void () ->
-android.arch.lifecycle.LifecycleDispatcher$DestructionReportFragment -> android.arch.lifecycle.f$a:
- void () ->
- void onPause() -> a_
- void onStop() -> c
- void onDestroy() -> a
- void dispatch(android.arch.lifecycle.Lifecycle$Event) -> a
-android.arch.lifecycle.LifecycleDispatcher$DispatcherActivityCallback -> android.arch.lifecycle.f$b:
- android.arch.lifecycle.LifecycleDispatcher$FragmentCallback mFragmentCallback -> a
- void () ->
- void onActivityCreated(android.app.Activity,android.os.Bundle) -> onActivityCreated
- void onActivityStopped(android.app.Activity) -> onActivityStopped
- void onActivitySaveInstanceState(android.app.Activity,android.os.Bundle) -> onActivitySaveInstanceState
-android.arch.lifecycle.LifecycleDispatcher$FragmentCallback -> android.arch.lifecycle.f$c:
- void () ->
- void onFragmentCreated(android.support.v4.app.FragmentManager,android.support.v4.app.Fragment,android.os.Bundle) -> a
- void onFragmentStarted(android.support.v4.app.FragmentManager,android.support.v4.app.Fragment) -> b
- void onFragmentResumed(android.support.v4.app.FragmentManager,android.support.v4.app.Fragment) -> c
-android.arch.lifecycle.LifecycleObserver -> android.arch.lifecycle.g:
-android.arch.lifecycle.LifecycleOwner -> android.arch.lifecycle.h:
- android.arch.lifecycle.Lifecycle getLifecycle() -> d
-android.arch.lifecycle.LifecycleRegistry -> android.arch.lifecycle.i:
- android.arch.core.internal.FastSafeIterableMap mObserverMap -> a
- android.arch.lifecycle.Lifecycle$State mState -> b
- java.lang.ref.WeakReference mLifecycleOwner -> c
- int mAddingObserverCounter -> d
- boolean mHandlingEvent -> e
- boolean mNewEventOccurred -> f
- java.util.ArrayList mParentStates -> g
- void (android.arch.lifecycle.LifecycleOwner) ->
- void markState(android.arch.lifecycle.Lifecycle$State) -> a
- void handleLifecycleEvent(android.arch.lifecycle.Lifecycle$Event) -> a
- void moveToState(android.arch.lifecycle.Lifecycle$State) -> b
- boolean isSynced() -> b
- void popParentState() -> c
- void pushParentState(android.arch.lifecycle.Lifecycle$State) -> c
- void removeObserver(android.arch.lifecycle.LifecycleObserver) -> a
- android.arch.lifecycle.Lifecycle$State getCurrentState() -> a
- android.arch.lifecycle.Lifecycle$State getStateAfter(android.arch.lifecycle.Lifecycle$Event) -> b
- android.arch.lifecycle.Lifecycle$Event downEvent(android.arch.lifecycle.Lifecycle$State) -> d
- android.arch.lifecycle.Lifecycle$Event upEvent(android.arch.lifecycle.Lifecycle$State) -> e
- void forwardPass(android.arch.lifecycle.LifecycleOwner) -> a
- void backwardPass(android.arch.lifecycle.LifecycleOwner) -> b
- void sync() -> d
- android.arch.lifecycle.Lifecycle$State min(android.arch.lifecycle.Lifecycle$State,android.arch.lifecycle.Lifecycle$State) -> a
-android.arch.lifecycle.LifecycleRegistry$1 -> android.arch.lifecycle.i$1:
- int[] $SwitchMap$android$arch$lifecycle$Lifecycle$Event -> a
- int[] $SwitchMap$android$arch$lifecycle$Lifecycle$State -> b
- void () ->
-android.arch.lifecycle.LifecycleRegistry$ObserverWithState -> android.arch.lifecycle.i$a:
- android.arch.lifecycle.Lifecycle$State mState -> a
- android.arch.lifecycle.GenericLifecycleObserver mLifecycleObserver -> b
- void dispatchEvent(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event) -> a
-android.arch.lifecycle.LifecycleRegistryOwner -> android.arch.lifecycle.j:
- android.arch.lifecycle.LifecycleRegistry getLifecycle() -> a
-android.arch.lifecycle.LiveData -> android.arch.lifecycle.LiveData:
- java.lang.Object NOT_SET -> a
- android.arch.lifecycle.LifecycleOwner ALWAYS_ON -> b
- android.arch.core.internal.SafeIterableMap mObservers -> c
- int mActiveCount -> d
- java.lang.Object mData -> e
- int mVersion -> f
- boolean mDispatchingValue -> g
- boolean mDispatchInvalidated -> h
- void considerNotify(android.arch.lifecycle.LiveData$LifecycleBoundObserver) -> a
- void dispatchingValue(android.arch.lifecycle.LiveData$LifecycleBoundObserver) -> b
- void removeObserver(android.arch.lifecycle.Observer) -> a
- void onActive() -> a
- void onInactive() -> b
- boolean isActiveState(android.arch.lifecycle.Lifecycle$State) -> a
- void assertMainThread(java.lang.String) -> a
- int access$300(android.arch.lifecycle.LiveData) -> a
- int access$302(android.arch.lifecycle.LiveData,int) -> a
- void access$400(android.arch.lifecycle.LiveData,android.arch.lifecycle.LiveData$LifecycleBoundObserver) -> a
- void () ->
-android.arch.lifecycle.LiveData$1 -> android.arch.lifecycle.LiveData$1:
- android.arch.lifecycle.LifecycleRegistry mRegistry -> a
- void () ->
- android.arch.lifecycle.LifecycleRegistry init() -> a
- android.arch.lifecycle.Lifecycle getLifecycle() -> d
-android.arch.lifecycle.LiveData$LifecycleBoundObserver -> android.arch.lifecycle.LiveData$LifecycleBoundObserver:
- android.arch.lifecycle.LifecycleOwner owner -> a
- android.arch.lifecycle.Observer observer -> b
- boolean active -> c
- int lastVersion -> d
- android.arch.lifecycle.LiveData this$0 -> e
- void onStateChanged(android.arch.lifecycle.LifecycleOwner,android.arch.lifecycle.Lifecycle$Event) -> a
- void activeStateChanged(boolean) -> a
-android.arch.lifecycle.MethodCallsLogger -> android.arch.lifecycle.k:
- java.util.Map mCalledMethods -> a
- void () ->
-android.arch.lifecycle.Observer -> android.arch.lifecycle.l:
- void onChanged(java.lang.Object) -> a
-android.arch.lifecycle.ProcessLifecycleOwner -> android.arch.lifecycle.m:
- int mStartedCounter -> a
- int mResumedCounter -> b
- boolean mPauseSent -> c
- boolean mStopSent -> d
- android.os.Handler mHandler -> e
- android.arch.lifecycle.LifecycleRegistry mRegistry -> f
- java.lang.Runnable mDelayedPauseRunnable -> g
- android.arch.lifecycle.ReportFragment$ActivityInitializationListener mInitializationListener -> h
- android.arch.lifecycle.ProcessLifecycleOwner sInstance -> i
- void init(android.content.Context) -> a
- void activityStarted() -> a
- void activityResumed() -> b
- void activityPaused() -> c
- void activityStopped() -> e
- void dispatchPauseIfNeeded() -> f
- void dispatchStopIfNeeded() -> g
- void () ->
- void attach(android.content.Context) -> b
- android.arch.lifecycle.Lifecycle getLifecycle() -> d
- void access$000(android.arch.lifecycle.ProcessLifecycleOwner) -> a
- void access$100(android.arch.lifecycle.ProcessLifecycleOwner) -> b
- android.arch.lifecycle.ReportFragment$ActivityInitializationListener access$200(android.arch.lifecycle.ProcessLifecycleOwner) -> c
- void