From fb47217a8b10a3dafce54b2c95e2580bf3cbe7aa Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 6 Mar 2019 11:42:59 +0100 Subject: [PATCH] Added FavoriteSessionFinder + related tests --- .../android/ExampleInstrumentedUnitTest.kt | 2 +- .../android/FavoriteSessionUnitTest.kt | 80 +++++++++++ .../android/RealmInstrumentedUnitTest.kt | 3 - .../model/utils/FavoriteSessionFinder.kt | 131 ++++++++++++++++++ 4 files changed, 212 insertions(+), 4 deletions(-) create mode 100644 app/src/androidTest/java/net/pokeranalytics/android/FavoriteSessionUnitTest.kt create mode 100644 app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt diff --git a/app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt index 85ef68bf..b9ff447a 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt @@ -503,7 +503,7 @@ class ExampleInstrumentedUnitTest : RealmInstrumentedUnitTest() { // } } - +// // @Test // fun testDurationConversion() { // diff --git a/app/src/androidTest/java/net/pokeranalytics/android/FavoriteSessionUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/FavoriteSessionUnitTest.kt new file mode 100644 index 00000000..e3a6343c --- /dev/null +++ b/app/src/androidTest/java/net/pokeranalytics/android/FavoriteSessionUnitTest.kt @@ -0,0 +1,80 @@ +package net.pokeranalytics.android + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import net.pokeranalytics.android.model.realm.Location +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.model.utils.FavoriteSessionFinder +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) + +class FavoriteSessionUnitTest : RealmInstrumentedUnitTest() { + + @Test + fun testFavoriteWithoutLocation() { + + val realm = this.mockRealm + realm.beginTransaction() + + val s1 = realm.createObject(Session::class.java, "1") + val s2 = realm.createObject(Session::class.java, "2") + val s3 = realm.createObject(Session::class.java, "3") + + s1.cgBigBlind = 4.0 + s2.cgBigBlind = 4.0 + s3.cgBigBlind = 1.0 + + realm.insert(s1) + realm.insert(s2) + realm.insert(s3) + + realm.commitTransaction() + val favSession = FavoriteSessionFinder.favoriteSession(Session.Type.CASH_GAME, null, realm, InstrumentationRegistry.getInstrumentation().targetContext) + + if (favSession != null) { + Assert.assertEquals(4.0, favSession.cgBigBlind) + } else { + Assert.fail("session shouldn't be null") + } + + } + + @Test + fun testFavoriteWithLocation() { + + val realm = this.mockRealm + realm.beginTransaction() + + val s1 = realm.createObject(Session::class.java, "1") + val s2 = realm.createObject(Session::class.java, "2") + val s3 = realm.createObject(Session::class.java, "3") + + val loc1 = realm.createObject(Location::class.java, "1") + val loc2 = realm.createObject(Location::class.java, "2") + + s1.cgBigBlind = 4.0 + s2.cgBigBlind = 4.0 + s3.cgBigBlind = 1.0 + + s1.location = loc1 + s2.location = loc1 + s3.location = loc2 + + realm.insert(s1) + realm.insert(s2) + realm.insert(s3) + + realm.commitTransaction() + val favSession = FavoriteSessionFinder.favoriteSession(Session.Type.CASH_GAME, loc2, realm, InstrumentationRegistry.getInstrumentation().targetContext) + + if (favSession != null) { + Assert.assertEquals(1.0, favSession.cgBigBlind) + } else { + Assert.fail("session shouldn't be null") + } + + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/net/pokeranalytics/android/RealmInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/RealmInstrumentedUnitTest.kt index 13879f8f..3076297e 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/RealmInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/RealmInstrumentedUnitTest.kt @@ -14,8 +14,6 @@ open class RealmInstrumentedUnitTest { @Before fun setup() { -// Looper.prepare() - val testConfig = RealmConfiguration.Builder().inMemory().name("test-realm").build() Realm.setDefaultConfiguration(testConfig) this.mockRealm = Realm.getDefaultInstance() @@ -29,7 +27,6 @@ open class RealmInstrumentedUnitTest { @After @Throws(Exception::class) public fun tearDown() { -// Looper.loop() this.mockRealm.close() } diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt new file mode 100644 index 00000000..37ee9326 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt @@ -0,0 +1,131 @@ +package net.pokeranalytics.android.model.utils + +import android.content.Context +import io.realm.Realm +import io.realm.Sort +import net.pokeranalytics.android.model.realm.Location +import net.pokeranalytics.android.model.realm.Session +import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow + +/** + * Returns all significant parameters concatenated in a String + * Not suitable for display + */ +fun Session.parameterRepresentation(context: Context) : String { + var representation = "" + + this.significantFields().forEach { + representation += this.stringForRow(it, context) + } + return representation + +} + +/** + * Returns a list of fields used to determine which kind of session is favorite + */ +private fun Session.significantFields() : List { + when (this.type) { + Session.Type.CASH_GAME.ordinal -> { + return listOf( + SessionRow.GAME, + SessionRow.INITIAL_BUY_IN, + SessionRow.BANKROLL, + SessionRow.TABLE_SIZE, + SessionRow.TOURNAMENT_TYPE + ) + } + Session.Type.TOURNAMENT.ordinal -> { + return listOf( + SessionRow.GAME, + SessionRow.BLINDS, + SessionRow.BANKROLL, + SessionRow.TABLE_SIZE + ) + } + } + throw Exception("A session should always have a type: tournament or CG") +} + +/** + * A class providing convenience method to determine the favorite session of the user at a location + */ +class FavoriteSessionFinder { + + /** + * A counter convenience class + */ + class Counter(session: Session) { + + var session: Session = session + var counter: Int = 1 + + fun increment() { + this.counter++ + } + + } + + companion object { + + private val FAVORITE_SIGNIFICANT_SESSIONS = 15L + + /** + * Copies the favorite session parameters on the [newSession] + */ + fun copyParametersFromFavoriteSession(newSession: Session, location: Location?, context: Context) { + + val favoriteSession = FavoriteSessionFinder.favoriteSession(newSession.type, location, newSession.realm, context) + + favoriteSession?.let { fav -> + + newSession.limit = fav.limit + newSession.game = fav.game + newSession.bankroll = fav.bankroll + newSession.tableSize = fav.tableSize + + when (newSession.type) { + Session.Type.CASH_GAME.ordinal -> { + newSession.cgSmallBlind = fav.cgSmallBlind + newSession.cgBigBlind = fav.cgBigBlind + } + Session.Type.TOURNAMENT.ordinal -> { + newSession.tournamentEntryFee = fav.tournamentEntryFee + } + } + } + + } + + /** + * Determines the favorite session given a [sessionType] and an optional [location] + */ + private fun favoriteSession(sessionType: Int, location: Location?, realm: Realm, context: Context) : Session? { + + var lastSessionsQuery = realm.where(Session::class.java).equalTo("type", sessionType) + if (location != null) { + lastSessionsQuery.equalTo("location.id", location.id) + } + val lastSessions = lastSessionsQuery + .sort("timeFrame.startDate", Sort.DESCENDING) + .limit(FAVORITE_SIGNIFICANT_SESSIONS) + .findAll() + + var counters= hashMapOf() + lastSessions.forEach { session -> + val representation = session.parameterRepresentation(context) + val counter = counters[representation] + if (counter != null) { + counter.increment() + } else { + counters[representation] = Counter(session) + } + } + + val sortedCounters = counters.values.sortedBy { it.counter } + return sortedCounters.first().session + } + + } + +} \ No newline at end of file