You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
poker-analytics/app/src/androidTest/java/net/pokeranalytics/android/StatsInstrumentedUnitTest.kt

625 lines
17 KiB

package net.pokeranalytics.android
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.realm.Realm
import io.realm.RealmList
import io.realm.RealmResults
import io.realm.kotlin.where
import net.pokeranalytics.android.calculus.Calculator
import net.pokeranalytics.android.calculus.ComputedResults
import net.pokeranalytics.android.calculus.ComputableGroup
import net.pokeranalytics.android.calculus.Stat
import net.pokeranalytics.android.model.Limit
import net.pokeranalytics.android.model.realm.*
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import timber.log.Timber
import java.text.SimpleDateFormat
import java.time.LocalDate
import java.time.Period
import java.util.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() {
// convenience extension
fun Session.Companion.testInstance(
netResult: Double = 0.0,
isTournament: Boolean = false,
startDate: Date = Date(),
endDate: Int = 1,
bankroll: Bankroll? = null,
game: Game? = null,
location : Location? = null,
tournamentName: TournamentName? = null,
tournamentFeatures: RealmList<TournamentFeature> = RealmList(),
numberOfTable: Int = 1,
limit: Int? = null,
tableSize: Int? = null
): Session {
val session: Session = Session.newInstance(super.mockRealm, isTournament, bankroll)
session.game = game
session.location = location
session.tournamentFeatures = tournamentFeatures
session.tournamentName = tournamentName
session.limit = limit
session.numberOfTables = numberOfTable
session.tableSize = tableSize
session.result?.netResult = netResult
session.startDate = startDate
val cal = Calendar.getInstance() // creates calendar
cal.time = startDate // sets calendar time/date
cal.add(Calendar.HOUR_OF_DAY, endDate) // adds one hour
session.endDate = cal.time // returns new date object, one hour in the future
return session
}
@Test
fun testSessionNetResultOnLoad() {
val realm = mockRealm
realm.beginTransaction()
for (index in 0..100) {
Session.testInstance((-2000..2000).random().toDouble())
println("*** creating ${index}")
}
realm.commitTransaction()
var d1 = Date()
var result = realm.where(Result::class.java).sum("netResult")
var d2 = Date()
val duration = (d2.time - d1.time)
println("*** ended in ${duration} milliseconds")
}
@Test
fun testSessionStats() {
val realm = this.mockRealm
realm.beginTransaction()
val s1 = realm.createObject(Session::class.java, "1")
val s2 = realm.createObject(Session::class.java, "2")
s1.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
s2.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
s1.result?.buyin = 100.0 // net result = -100
s2.result?.buyin = 200.0
s2.result?.cashout = 500.0 // net result = 300
s1.cgBigBlind = 0.5 // bb net result = -200bb
s2.cgBigBlind = 2.0 // bb net result = 150bb
s2.tableSize = 5
realm.insert(s1)
realm.insert(s2)
realm.commitTransaction()
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 10:00")
val ed1 = sdf.parse("01/1/2019 11:00") // 1 hour
val sd2 = sdf.parse("02/1/2019 08:00")
val ed2 = sdf.parse("02/1/2019 11:00") // 3 hours
realm.beginTransaction()
s1.startDate = sd1
s1.endDate = ed1
s2.startDate = sd2
s2.endDate = ed2
realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2)
realm.commitTransaction()
val sessions = realm.where(Session::class.java).findAll()
val group = ComputableGroup(name = "test", computables = sessions)
val options = Calculator.Options()
options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)
val results: ComputedResults = Calculator.compute(group, options)
val delta = 0.01
val sum = results.computedStat(Stat.NETRESULT)
if (sum != null) {
assertEquals(200.0, sum.value, delta)
} else {
Assert.fail("No Net result stat")
}
val average = results.computedStat(Stat.AVERAGE)
if (average != null) {
assertEquals(100.0, average.value, delta)
} else {
Assert.fail("No AVERAGE stat")
}
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assertEquals(4.0, duration.value, delta)
} else {
Assert.fail("No netDuration stat")
}
val hourlyRate = results.computedStat(Stat.HOURLY_RATE)
if (hourlyRate != null) {
assertEquals(50.0, hourlyRate.value, delta)
} else {
Assert.fail("No houry rate stat")
}
val handsPlayed = results.computedStat(Stat.HANDS_PLAYED)
if (handsPlayed != null) {
assertEquals(177.77, handsPlayed.value, delta)
} else {
Assert.fail("No hands played stat")
}
val numberOfGames = results.computedStat(Stat.NUMBER_OF_GAMES)
if (numberOfGames != null) {
assertEquals(2, numberOfGames.value.toInt())
} else {
Assert.fail("No numberOfGames stat")
}
val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
if (numberOfSets != null) {
assertEquals(2, numberOfSets.value.toInt())
} else {
Assert.fail("No numberOfSets stat")
}
val avgBuyin = results.computedStat(Stat.AVERAGE_BUYIN)
if (avgBuyin != null) {
assertEquals(150.0, avgBuyin.value, delta)
} else {
Assert.fail("No avgBuyin stat")
}
val avgDuration = results.computedStat(Stat.AVERAGE_DURATION)
if (avgDuration != null) {
assertEquals(2.0, avgDuration.value, delta)
} else {
Assert.fail("No avgDuration stat")
}
val roi = results.computedStat(Stat.ROI)
if (roi != null) {
assertEquals(200 / 300.0, roi.value, delta)
} else {
Assert.fail("No roi stat")
}
val avgBBNet = results.computedStat(Stat.AVERAGE_NET_BB)
if (avgBBNet != null) {
assertEquals(-25.0, avgBBNet.value, delta)
} else {
Assert.fail("No avgBBNet stat")
}
val bbHourlyRate = results.computedStat(Stat.HOURLY_RATE_BB)
if (bbHourlyRate != null) {
assertEquals(-12.5, bbHourlyRate.value, delta)
} else {
Assert.fail("No bbHourlyRate stat")
}
val netbbPer100Hands = results.computedStat(Stat.NET_BB_PER_100_HANDS)
if (netbbPer100Hands != null) {
assertEquals(-28.12, netbbPer100Hands.value, delta)
} else {
Assert.fail("No netbbPer100Hands stat")
}
val std = results.computedStat(Stat.STANDARD_DEVIATION)
if (std != null) {
assertEquals(200.0, std.value, delta)
} else {
Assert.fail("No std stat")
}
val stdHourly = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY)
if (stdHourly != null) {
assertEquals(111.8, stdHourly.value, delta)
} else {
Assert.fail("No stdHourly stat")
}
val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS)
if (std100 != null) {
assertEquals(497.54, std100.value, delta)
} else {
Assert.fail("No std100 stat")
}
}
@Test
fun testOverlappingSessions1() {
val realm = this.mockRealm
realm.beginTransaction()
val s1 = realm.createObject(Session::class.java, "1")
val s2 = realm.createObject(Session::class.java, "2")
s1.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
s2.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
realm.insert(s1)
realm.insert(s2)
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 09:00")
val ed1 = sdf.parse("01/1/2019 10:00")
val sd2 = sdf.parse("01/1/2019 08:00")
val ed2 = sdf.parse("01/1/2019 11:00")
s1.startDate = sd1
s1.endDate = ed1
s2.startDate = sd2
s2.endDate = ed2
// netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
// netDuration = 4h, hourly = 100, bb100 = 150 / 75 * 100 = +200
realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2)
realm.commitTransaction()
val sessions = realm.where(Session::class.java).findAll()
val group = ComputableGroup(name = "test", computables = sessions)
val options = Calculator.Options()
options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)
val results: ComputedResults = Calculator.compute(group, options)
val delta = 0.01
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assertEquals(3.0, duration.value, delta)
} else {
Assert.fail("No Net result stat")
}
val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
if (numberOfSets != null) {
assertEquals(1, numberOfSets.value.toInt())
} else {
Assert.fail("No numberOfSets stat")
}
val numberOfGames = results.computedStat(Stat.NUMBER_OF_GAMES)
if (numberOfGames != null) {
assertEquals(2, numberOfGames.value.toInt())
} else {
Assert.fail("No numberOfSets stat")
}
}
@Test
fun testOverlappingSessions2() {
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")
realm.insert(s1)
realm.insert(s2)
realm.insert(s3)
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 05:00")
val ed1 = sdf.parse("01/1/2019 09:00") // 4h
val sd2 = sdf.parse("01/1/2019 07:00")
val ed2 = sdf.parse("01/1/2019 11:00") // 4h
val sd3 = sdf.parse("01/1/2019 03:00")
val ed3 = sdf.parse("01/1/2019 06:00") // 3h
s1.startDate = sd1
s1.endDate = ed1
s2.startDate = sd2
s2.endDate = ed2
s3.startDate = sd3
s3.endDate = ed3
realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2)
realm.copyToRealmOrUpdate(s3)
realm.commitTransaction()
val sessions = realm.where(Session::class.java).findAll()
val group = ComputableGroup(name = "test", computables = sessions)
val options = Calculator.Options()
options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)
val results: ComputedResults = Calculator.compute(group, options)
val delta = 0.01
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assertEquals(8.0, duration.value, delta)
} else {
Assert.fail("No Net result stat")
}
val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
if (numberOfSets != null) {
assertEquals(1, numberOfSets.value.toInt())
} else {
Assert.fail("No numberOfSets stat")
}
val numberOfGames = results.computedStat(Stat.NUMBER_OF_GAMES)
if (numberOfGames != null) {
assertEquals(3, numberOfGames.value.toInt())
} else {
Assert.fail("No numberOfSets stat")
}
}
private var sessions: RealmResults<Session>? = null
// @Test
fun testOverlappingSessionDeletion() {
val realm = this.mockRealm
this.sessions = realm.where(Session::class.java).findAll() // monitor session deletions
this.sessions?.addChangeListener { _, changeSet ->
val deletedSessions =
realm.where(Session::class.java).`in`("id", changeSet.deletions.toTypedArray()).findAll()
deletedSessions.forEach { it.cleanup() }
}
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")
realm.insert(s1)
realm.insert(s2)
realm.insert(s3)
realm.commitTransaction()
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 05:00")
val ed1 = sdf.parse("01/1/2019 09:00")
val sd2 = sdf.parse("01/1/2019 07:00")
val ed2 = sdf.parse("01/1/2019 11:00")
val sd3 = sdf.parse("01/1/2019 03:00")
val ed3 = sdf.parse("01/1/2019 06:00")
realm.beginTransaction()
s1.startDate = sd1
s1.endDate = ed1
s2.startDate = sd2
s2.endDate = ed2
s3.startDate = sd3
s3.endDate = ed3
realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2)
realm.copyToRealmOrUpdate(s3)
realm.commitTransaction()
val sessions = realm.where(Session::class.java).findAll()
val group = ComputableGroup(name = "test", computables = sessions)
val options = Calculator.Options()
options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)
val results: ComputedResults = Calculator.compute(group, options)
val delta = 0.01
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assertEquals(8.0, duration.value, delta)
} else {
Assert.fail("No netDuration stat")
}
realm.executeTransaction {
s1.deleteFromRealm()
}
val group2 = ComputableGroup(name = "test", computables = sessions)
val results2: ComputedResults = Calculator.compute(group2, options)
val duration2 = results2.computedStat(Stat.DURATION)
if (duration2 != null) {
assertEquals(7.0, duration2.value, delta)
} else {
Assert.fail("No duration2 stat")
}
}
@Test
fun testSessionSetCount() {
val realm = this.mockRealm
realm.beginTransaction()
val s1 = realm.createObject(Session::class.java, "1")
s1.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
realm.insert(s1)
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 09:00")
val ed1 = sdf.parse("01/1/2019 10:00")
s1.startDate = sd1 // timeFrame?.setDate(sd1, ed1) // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
s1.endDate = ed1
realm.copyToRealmOrUpdate(s1)
realm.commitTransaction()
val sets = realm.where(SessionSet::class.java).findAll()
Assert.assertEquals(1, sets.size)
val set = sets.first()
if (set != null) {
Assert.assertEquals(sd1.time, set.startDate.time)
Assert.assertEquals(ed1.time, set.endDate.time)
} else {
Assert.fail("No set")
}
}
@Test
fun testSessionSetCount2() {
val realm = this.mockRealm
realm.beginTransaction()
val s1 = realm.createObject(Session::class.java, "1")
val s2 = realm.createObject(Session::class.java, "2")
s1.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
s2.result = realm.createObject(net.pokeranalytics.android.model.realm.Result::class.java)
realm.insert(s1)
realm.insert(s2)
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 09:00")
val ed1 = sdf.parse("01/1/2019 10:00")
val sd2 = sdf.parse("01/2/2018 09:00")
val ed2 = sdf.parse("01/2/2018 10:00")
s1.startDate = sd1
s1.endDate = ed1
s2.startDate = sd2
s2.endDate = ed2
// s1.timeFrame?.setDate(sd1, ed1) // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
// s2.timeFrame?.setDate(sd2, ed2) // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800
realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2)
realm.commitTransaction()
val sets = realm.where(SessionSet::class.java).findAll()
Assert.assertEquals(2, sets.size)
// val set = sets.first()
// if (set != null) {
// Assert.assertEquals(sd1.time, set.timeFrame?.startDate?.time)
// Assert.assertEquals(ed1.time, set.timeFrame?.endDate?.time)
// } else {
// Assert.fail("No set")
// }
}
//
// @Test
// fun testDurationConversion() {
//
// val duration = 6.7555561274509826
// val longDuration = duration.toLong()
// val formatted = longDuration.toMinutes()
//
// assert(formatted == "11:00")
// }
@Test
fun testSessionRestartInOverlappingSessions() {
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")
realm.insert(s1)
realm.insert(s2)
realm.insert(s3)
val sdf = SimpleDateFormat("dd/M/yyyy hh:mm")
val sd1 = sdf.parse("01/1/2019 05:00")
val ed1 = sdf.parse("01/1/2019 09:00") // 4h
val sd2 = sdf.parse("01/1/2019 07:00")
val ed2 = sdf.parse("01/1/2019 11:00") // 4h
val sd3 = sdf.parse("01/1/2019 03:00")
val ed3 = sdf.parse("01/1/2019 06:00") // 3h
s1.startDate = sd1
s1.endDate = ed1
s2.startDate = sd2
s2.endDate = ed2
s3.startDate = sd3
s3.endDate = ed3
realm.copyToRealmOrUpdate(s1)
realm.copyToRealmOrUpdate(s2)
realm.copyToRealmOrUpdate(s3)
realm.commitTransaction()
realm.executeTransaction {
s1.endDate = null
}
val sessions = realm.where(Session::class.java).findAll()
val group = ComputableGroup(name = "test", computables = sessions)
val options = Calculator.Options()
// options.displayedStats = listOf(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION)
val results: ComputedResults = Calculator.compute(group, options)
val delta = 0.01
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assertEquals(7.0, duration.value, delta)
} else {
Assert.fail("No Net result stat")
}
val numberOfSets = results.computedStat(Stat.NUMBER_OF_SETS)
if (numberOfSets != null) {
assertEquals(2, numberOfSets.value.toInt())
} else {
Assert.fail("No numberOfSets stat")
}
}
}