package net.pokeranalytics.android import androidx.test.ext.junit.runners.AndroidJUnit4 import io.realm.RealmResults import net.pokeranalytics.android.calculus.Calculator import net.pokeranalytics.android.calculus.ComputedResults import net.pokeranalytics.android.calculus.SessionGroup import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.TimeFrame import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith import java.text.SimpleDateFormat 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 ExampleInstrumentedUnitTest : RealmInstrumentedUnitTest() { // convenience extension fun Session.Companion.testInstance(netResult: Double, startDate: Date, endDate: Date?): Session { val session: Session = Session.newInstance() session.result?.netResult = netResult session.timeFrame?.setDate(startDate, endDate) return session } @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.timeFrame = realm.createObject(TimeFrame::class.java) s2.timeFrame = realm.createObject(TimeFrame::class.java) 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 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") val sd2 = sdf.parse("02/1/2019 08:00") val ed2 = sdf.parse("02/1/2019 11:00") realm.beginTransaction() s1.timeFrame?.setDate(sd1, ed1) // duration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800 s2.timeFrame?.setDate(sd2, ed2) // duration = 3h, 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 = SessionGroup(name = "test", sessions = 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 duration 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(100.0, 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(-50.0, 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(559.01, 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.timeFrame = realm.createObject(TimeFrame::class.java) s2.timeFrame = realm.createObject(TimeFrame::class.java) 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) realm.commitTransaction() 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") realm.beginTransaction() s1.timeFrame?.setDate(sd1, ed1) // duration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800 s2.timeFrame?.setDate(sd2, ed2) // duration = 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 = SessionGroup(name = "test", sessions = 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") s1.timeFrame = realm.createObject(TimeFrame::class.java) s2.timeFrame = realm.createObject(TimeFrame::class.java) s3.timeFrame = realm.createObject(TimeFrame::class.java) 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.timeFrame?.setDate(sd1, ed1) // duration = 4h s2.timeFrame?.setDate(sd2, ed2) // duration = 4h s3.timeFrame?.setDate(sd3, ed3) // duration = 3h realm.copyToRealmOrUpdate(s1) realm.copyToRealmOrUpdate(s2) realm.copyToRealmOrUpdate(s3) realm.commitTransaction() val sessions = realm.where(Session::class.java).findAll() val group = SessionGroup(name = "test", sessions = 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") } } var sessions: RealmResults? = null // @Test fun testOverlappingSessionDeletion() { val realm = this.mockRealm this.sessions = realm.where(Session::class.java).findAll() // monitor session deletions this.sessions?.addChangeListener { t, 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") s1.timeFrame = realm.createObject(TimeFrame::class.java) s2.timeFrame = realm.createObject(TimeFrame::class.java) s3.timeFrame = realm.createObject(TimeFrame::class.java) 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.timeFrame?.setDate(sd1, ed1) // duration = 4h s2.timeFrame?.setDate(sd2, ed2) // duration = 4h s3.timeFrame?.setDate(sd3, ed3) // duration = 3h realm.copyToRealmOrUpdate(s1) realm.copyToRealmOrUpdate(s2) realm.copyToRealmOrUpdate(s3) realm.commitTransaction() val sessions = realm.where(Session::class.java).findAll() val group = SessionGroup(name = "test", sessions = 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 duration stat") } // realm.beginTransaction() // s1.deleteFromRealm() // realm.commitTransaction() realm.executeTransaction { s1.deleteFromRealm() } val group2 = SessionGroup(name = "test", sessions = 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") } } }