parent
6dba82a895
commit
9c3134d866
@ -1,518 +0,0 @@ |
|||||||
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.SessionSet |
|
||||||
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(super.mockRealm, false) |
|
||||||
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) // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800 |
|
||||||
s2.timeFrame?.setDate(sd2, ed2) // netDuration = 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 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(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) |
|
||||||
|
|
||||||
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.timeFrame?.setDate(sd1, ed1) // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800 |
|
||||||
s2.timeFrame?.setDate(sd2, ed2) // 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 = 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) |
|
||||||
|
|
||||||
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") |
|
||||||
|
|
||||||
s1.timeFrame?.setDate(sd1, ed1) // netDuration = 4h |
|
||||||
s2.timeFrame?.setDate(sd2, ed2) // netDuration = 4h |
|
||||||
s3.timeFrame?.setDate(sd3, ed3) // netDuration = 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<Session>? = 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) // netDuration = 4h |
|
||||||
s2.timeFrame?.setDate(sd2, ed2) // netDuration = 4h |
|
||||||
s3.timeFrame?.setDate(sd3, ed3) // netDuration = 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 netDuration stat") |
|
||||||
} |
|
||||||
|
|
||||||
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") |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Test |
|
||||||
fun testSessionSetCount() { |
|
||||||
|
|
||||||
val realm = this.mockRealm |
|
||||||
|
|
||||||
realm.beginTransaction() |
|
||||||
val s1 = realm.createObject(Session::class.java, "1") |
|
||||||
|
|
||||||
s1.timeFrame = realm.createObject(TimeFrame::class.java) |
|
||||||
|
|
||||||
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.timeFrame?.setDate(sd1, ed1) // netDuration = 1h, hourly = -100, bb100 = -200bb / 25hands * 100 = -800 |
|
||||||
|
|
||||||
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.timeFrame?.startDate?.time) |
|
||||||
Assert.assertEquals(ed1.time, set.timeFrame?.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.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) |
|
||||||
|
|
||||||
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.timeFrame?.let { |
|
||||||
it.setStart(sd1) |
|
||||||
it.setEnd(ed1) |
|
||||||
} |
|
||||||
|
|
||||||
s2.timeFrame?.let { |
|
||||||
it.setStart(sd2) |
|
||||||
it.setEnd(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") |
|
||||||
// } |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
@ -0,0 +1,573 @@ |
|||||||
|
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.SessionSet |
||||||
|
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 StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() { |
||||||
|
|
||||||
|
// convenience extension |
||||||
|
fun Session.Companion.testInstance(netResult: Double, startDate: Date, endDate: Date?): Session { |
||||||
|
val session: Session = Session.newInstance(super.mockRealm, false) |
||||||
|
session.result?.netResult = netResult |
||||||
|
session.startDate = startDate |
||||||
|
session.endDate = 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.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.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 = 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 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(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.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 = 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") |
||||||
|
|
||||||
|
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 = 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") |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
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 = 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 netDuration stat") |
||||||
|
} |
||||||
|
|
||||||
|
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") |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@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 = 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(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") |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
package net.pokeranalytics.android.model.interfaces |
||||||
|
|
||||||
|
import java.util.* |
||||||
|
|
||||||
|
interface Timed { |
||||||
|
|
||||||
|
var startDate: Date |
||||||
|
|
||||||
|
fun endDate() : Date |
||||||
|
|
||||||
|
var breakDuration: Long |
||||||
|
|
||||||
|
var netDuration: Long |
||||||
|
|
||||||
|
/** |
||||||
|
* Computes the net netDuration of the session |
||||||
|
*/ |
||||||
|
fun computeDuration() { |
||||||
|
this.netDuration = this.endDate().time - this.startDate.time - this.breakDuration |
||||||
|
} |
||||||
|
|
||||||
|
// fun hourlyDuration() : Double { |
||||||
|
// return this.netDuration / 3600000.0 // 3.6 millions of milliseconds |
||||||
|
// } |
||||||
|
|
||||||
|
var hourlyDuration: Double |
||||||
|
get() = this.netDuration / 3600000.0 |
||||||
|
set(value) = TODO() |
||||||
|
|
||||||
|
} |
||||||
@ -1,280 +1,288 @@ |
|||||||
package net.pokeranalytics.android.model.realm |
//package net.pokeranalytics.android.model.realm |
||||||
|
// |
||||||
import io.realm.RealmObject |
//import io.realm.RealmObject |
||||||
import io.realm.RealmQuery |
//import io.realm.RealmQuery |
||||||
import io.realm.RealmResults |
//import io.realm.RealmResults |
||||||
import io.realm.annotations.Ignore |
//import io.realm.annotations.Ignore |
||||||
import io.realm.annotations.LinkingObjects |
//import io.realm.annotations.LinkingObjects |
||||||
import net.pokeranalytics.android.exceptions.ModelException |
//import net.pokeranalytics.android.exceptions.ModelException |
||||||
import timber.log.Timber |
//import timber.log.Timber |
||||||
import java.util.* |
//import java.util.* |
||||||
|
// |
||||||
open class TimeFrame : RealmObject() { |
//open class TimeFrame : RealmObject() { |
||||||
|
// |
||||||
// A start date |
// // A start date |
||||||
var startDate: Date = Date() |
// var startDate: Date = Date() |
||||||
private set(value) { |
// private set(value) { |
||||||
field = value |
// field = value |
||||||
this.computeDuration() |
// this.computeDuration() |
||||||
} |
// } |
||||||
|
// |
||||||
// An end date |
// // An end date |
||||||
var endDate: Date? = null |
// var endDate: Date? = null |
||||||
private set(value) { |
// private set(value) { |
||||||
field = value |
// field = value |
||||||
this.computeDuration() |
// this.computeDuration() |
||||||
} |
// } |
||||||
|
// |
||||||
// The latest pause date |
// // The latest pause date |
||||||
var pauseDate: Date? = null |
// var pauseDate: Date? = null |
||||||
set(value) { |
// set(value) { |
||||||
field?.let { |
// field?.let { |
||||||
if (value == null && field != null) { |
// if (value == null && field != null) { |
||||||
breakDuration += Date().time - it.time |
// breakDuration += Date().time - it.time |
||||||
} |
// } |
||||||
} |
// } |
||||||
field = value |
// field = value |
||||||
this.computeDuration() |
// this.computeDuration() |
||||||
} |
// } |
||||||
|
// |
||||||
// The break netDuration |
// // The break netDuration |
||||||
var breakDuration: Long = 0L |
// var breakDuration: Long = 0L |
||||||
set(value) { |
// set(value) { |
||||||
field = value |
// field = value |
||||||
this.computeDuration() |
// this.computeDuration() |
||||||
} |
// } |
||||||
|
// |
||||||
// the total netDuration |
// // the total netDuration |
||||||
var netDuration: Long = 0L |
// var netDuration: Long = 0L |
||||||
private set |
// private set |
||||||
|
// |
||||||
var hourlyDuration: Double = 0.0 |
// var hourlyDuration: Double = 0.0 |
||||||
get() { |
// get() { |
||||||
return this.netDuration / 3600000.0 // 3.6 millions of milliseconds |
// return this.netDuration / 3600000.0 // 3.6 millions of milliseconds |
||||||
} |
// } |
||||||
|
// |
||||||
// indicates a state of pause |
// // Session |
||||||
var paused: Boolean = false |
// @LinkingObjects("timeFrame") |
||||||
|
// private val sessions: RealmResults<Session>? = null // we should have only one session |
||||||
// Session |
// |
||||||
@LinkingObjects("timeFrame") |
// @Ignore |
||||||
private val sessions: RealmResults<Session>? = null // we should have only one session |
// var session: Session? = null |
||||||
|
// get() = if (this.sessions != null && this.sessions.isEmpty()) null else this.sessions?.first() |
||||||
@Ignore |
// |
||||||
var session: Session? = null |
// // Group |
||||||
get() = if (this.sessions != null && this.sessions.isEmpty()) null else this.sessions?.first() |
// @LinkingObjects("timeFrame") |
||||||
|
// private val sets: RealmResults<SessionSet>? = null // we should have only one sessionGroup |
||||||
// Group |
// |
||||||
@LinkingObjects("timeFrame") |
// @Ignore |
||||||
private val sets: RealmResults<SessionSet>? = null // we should have only one sessionGroup |
// var set: SessionSet? = null |
||||||
|
// get() = this.sets?.first() |
||||||
@Ignore |
// |
||||||
var set: SessionSet? = null |
// fun setStart(startDate: Date) { |
||||||
get() = this.sets?.first() |
// this.startDate = startDate |
||||||
|
// this.session?.let { |
||||||
fun setStart(startDate: Date) { |
// this.notifySessionDateChange(it) |
||||||
this.startDate = startDate |
// } |
||||||
this.session?.let { |
// } |
||||||
this.notifySessionDateChange(it) |
// |
||||||
} |
// fun setEnd(endDate: Date?) { |
||||||
} |
// this.endDate = endDate |
||||||
|
// this.session?.let { |
||||||
fun setEnd(endDate: Date?) { |
// this.notifySessionDateChange(it) |
||||||
this.endDate = endDate |
// } |
||||||
this.session?.let { |
// } |
||||||
this.notifySessionDateChange(it) |
// |
||||||
} |
// fun setDate(startDate: Date, endDate: Date?) { |
||||||
} |
// this.startDate = startDate |
||||||
|
// this.endDate = endDate |
||||||
fun setDate(startDate: Date, endDate: Date?) { |
// |
||||||
this.startDate = startDate |
// this.session?.let { |
||||||
this.endDate = endDate |
// this.notifySessionDateChange(it) |
||||||
|
// } |
||||||
this.session?.let { |
// } |
||||||
this.notifySessionDateChange(it) |
// |
||||||
} |
// /** |
||||||
} |
// * Computes the net netDuration of the session |
||||||
|
// */ |
||||||
/** |
// private fun computeDuration() { |
||||||
* Computes the net netDuration of the session |
// var endDate: Date = this.endDate ?: Date() |
||||||
*/ |
// this.netDuration = endDate.time - this.startDate.time - this.breakDuration |
||||||
private fun computeDuration() { |
// } |
||||||
var endDate: Date = this.endDate ?: Date() |
// |
||||||
this.netDuration = endDate.time - this.startDate.time - this.breakDuration |
// /** |
||||||
} |
// * Queries all time frames that might be impacted by the date change |
||||||
|
// * Makes all necessary changes to keep sequential time frames |
||||||
/** |
// */ |
||||||
* Queries all time frames that might be impacted by the date change |
// fun notifySessionDateChange(owner: Session) { |
||||||
* Makes all necessary changes to keep sequential time frames |
// |
||||||
*/ |
// var query: RealmQuery<SessionSet> = this.realm.where(SessionSet::class.java) |
||||||
fun notifySessionDateChange(owner: Session) { |
// query.isNotNull("timeFrame") |
||||||
|
// |
||||||
var query: RealmQuery<SessionSet> = this.realm.where(SessionSet::class.java) |
//// Timber.d("this> sd = : ${this.startDate}, ed = ${this.endDate}") |
||||||
query.isNotNull("timeFrame") |
// |
||||||
|
// val sets = realm.where(SessionSet::class.java).findAll() |
||||||
// Timber.d("this> sd = : ${this.startDate}, ed = ${this.endDate}") |
//// Timber.d("set count = ${sets.size}") |
||||||
|
// |
||||||
val sets = realm.where(SessionSet::class.java).findAll() |
// if (this.endDate == null) { |
||||||
// Timber.d("set count = ${sets.size}") |
// query.greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||||
|
// .or() |
||||||
if (this.endDate == null) { |
// .greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
||||||
query.greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
// .or() |
||||||
.or() |
// .isNull("timeFrame.endDate") |
||||||
.greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
// } else { |
||||||
.or() |
// val endDate = this.endDate!! |
||||||
.isNull("timeFrame.endDate") |
// query |
||||||
} else { |
// .lessThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||||
val endDate = this.endDate!! |
// .greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
||||||
query |
// .or() |
||||||
.lessThanOrEqualTo("timeFrame.startDate", this.startDate) |
// .lessThanOrEqualTo("timeFrame.startDate", endDate) |
||||||
.greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
// .greaterThanOrEqualTo("timeFrame.endDate", endDate) |
||||||
.or() |
// .or() |
||||||
.lessThanOrEqualTo("timeFrame.startDate", endDate) |
// .greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||||
.greaterThanOrEqualTo("timeFrame.endDate", endDate) |
// .lessThanOrEqualTo("timeFrame.endDate", endDate) |
||||||
.or() |
// .or() |
||||||
.greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
// .isNull("timeFrame.endDate") |
||||||
.lessThanOrEqualTo("timeFrame.endDate", endDate) |
// .lessThanOrEqualTo("timeFrame.startDate", endDate) |
||||||
.or() |
// } |
||||||
.isNull("timeFrame.endDate") |
// |
||||||
.lessThanOrEqualTo("timeFrame.startDate", endDate) |
// val sessionGroups = query.findAll() |
||||||
} |
// |
||||||
|
// this.updateTimeFrames(sessionGroups, owner) |
||||||
val sessionGroups = query.findAll() |
// |
||||||
|
// } |
||||||
this.updateTimeFrames(sessionGroups, owner) |
// |
||||||
|
// /** |
||||||
} |
// * Update Time frames from sets |
||||||
|
// */ |
||||||
/** |
// private fun updateTimeFrames(sessionSets: RealmResults<SessionSet>, owner: Session) { |
||||||
* Update Time frames from sets |
// |
||||||
*/ |
// when (sessionSets.size) { |
||||||
private fun updateTimeFrames(sessionSets: RealmResults<SessionSet>, owner: Session) { |
// 0 -> this.createOrUpdateSessionSet(owner) |
||||||
|
// 1 -> this.updateSessionGroup(owner, sessionSets.first()!!) |
||||||
when (sessionSets.size) { |
// else -> this.mergeSessionGroups(owner, sessionSets) |
||||||
0 -> this.createSessionGroup(owner) |
// } |
||||||
1 -> this.updateSessionGroup(owner, sessionSets.first()!!) |
// |
||||||
else -> this.mergeSessionGroups(owner, sessionSets) |
// } |
||||||
} |
// |
||||||
|
// /** |
||||||
} |
// * Creates the session sessionGroup when the session has none |
||||||
|
// */ |
||||||
/** |
// private fun createOrUpdateSessionSet(owner: Session) { |
||||||
* Creates the session sessionGroup when the session has none |
// |
||||||
*/ |
// val set = owner.sessionSet |
||||||
private fun createSessionGroup(owner: Session) { |
// if (set != null) { |
||||||
|
// set.timeFrame?.startDate = this.startDate |
||||||
val set: SessionSet = SessionSet.newInstance(this.realm) |
// set.timeFrame?.endDate = this.endDate |
||||||
set.timeFrame?.let { |
// } else { |
||||||
it.startDate = this.startDate |
// this.createSessionSet(owner) |
||||||
it.endDate = this.endDate |
// } |
||||||
} ?: run { |
// |
||||||
throw ModelException("TimeFrame should never be null here") |
//// Timber.d("sd = : ${set.timeFrame?.startDate}, ed = ${set.timeFrame?.endDate}") |
||||||
} |
// Timber.d("netDuration 1 = : ${set?.timeFrame?.netDuration}") |
||||||
|
// |
||||||
owner.sessionSet = set |
// } |
||||||
|
// |
||||||
// Timber.d("sd = : ${set.timeFrame?.startDate}, ed = ${set.timeFrame?.endDate}") |
// fun createSessionSet(owner: Session) { |
||||||
Timber.d("netDuration 1 = : ${set.timeFrame?.netDuration}") |
// val set: SessionSet = SessionSet.newInstance(this.realm) |
||||||
|
// set.timeFrame?.let { |
||||||
} |
// it.startDate = this.startDate |
||||||
|
// it.endDate = this.endDate |
||||||
/** |
// } ?: run { |
||||||
* Single SessionSet update, the session might be the owner |
// throw ModelException("TimeFrame should never be null here") |
||||||
* Changes the sessionGroup timeframe using the current timeframe dates |
// } |
||||||
*/ |
// |
||||||
private fun updateSessionGroup(owner: Session, sessionSet: SessionSet) { |
// owner.sessionSet = set |
||||||
|
// } |
||||||
var timeFrame: TimeFrame = sessionSet.timeFrame!! // tested in the query |
// |
||||||
// timeFrame.setDate(this.startDate, this.endDate) |
// |
||||||
|
// /** |
||||||
val sisterSessions = sessionSet.sessions!! // shouldn't crash ever |
// * Single SessionSet update, the session might be the owner |
||||||
|
// * Changes the sessionGroup timeframe using the current timeframe dates |
||||||
// if we have only one session in the set and that it corresponds to the set |
// */ |
||||||
if (sessionSet.sessions?.size == 1 && sessionSet.sessions?.first() == owner) { |
// private fun updateSessionGroup(owner: Session, sessionSet: SessionSet) { |
||||||
timeFrame.setDate(this.startDate, this.endDate) |
// |
||||||
} else { // there are 2+ sessions to manage and possible splits |
// var timeFrame: TimeFrame = sessionSet.timeFrame!! // tested in the query |
||||||
|
//// timeFrame.setDate(this.startDate, this.endDate) |
||||||
val endDate = this.endDate |
// |
||||||
|
// val sisterSessions = sessionSet.sessions!! // shouldn't crash ever |
||||||
// case where all sessions are over but the set is not, we might have a split, so we delete the set and save everything again |
// |
||||||
if (endDate != null && sisterSessions.all { it.timeFrame?.endDate != null } && timeFrame.endDate == null) { |
// // if we have only one session in the set and that it corresponds to the set |
||||||
var sessions = mutableListOf<Session>(owner) |
// if (sessionSet.sessions?.size == 1 && sessionSet.sessions?.first() == owner) { |
||||||
sessionSet.sessions?.forEach { sessions.add(it) } |
// timeFrame.setDate(this.startDate, this.endDate) |
||||||
sessionSet.deleteFromRealm() |
// } else { // there are 2+ sessions to manage and possible splits |
||||||
sessions.forEach { it.timeFrame?.notifySessionDateChange(it) } |
// |
||||||
} else { |
// val endDate = this.endDate |
||||||
|
// |
||||||
if (this.startDate.before(timeFrame.startDate)) { |
// // case where all sessions are over but the set is not, we might have a split, so we delete the set and save everything again |
||||||
timeFrame.startDate = this.startDate |
// if (endDate != null && sisterSessions.all { it.timeFrame?.endDate != null } && timeFrame.endDate == null) { |
||||||
} |
// var sessions = mutableListOf<Session>(owner) |
||||||
if (endDate != null && timeFrame.endDate != null && endDate.after(timeFrame.endDate)) { |
// sessionSet.sessions?.forEach { sessions.add(it) } |
||||||
timeFrame.endDate = endDate |
// sessionSet.deleteFromRealm() |
||||||
} else if (endDate == null) { |
// sessions.forEach { it.timeFrame?.notifySessionDateChange(it) } |
||||||
timeFrame.endDate = null |
// } else { |
||||||
} |
// |
||||||
|
// if (this.startDate.before(timeFrame.startDate)) { |
||||||
owner.sessionSet = sessionSet |
// timeFrame.startDate = this.startDate |
||||||
|
// } |
||||||
// Timber.d("sd = : ${sessionSet.timeFrame?.startDate}, ed = ${sessionSet.timeFrame?.endDate}") |
// if (endDate != null && timeFrame.endDate != null && endDate.after(timeFrame.endDate)) { |
||||||
Timber.d("netDuration 2 = : ${sessionSet.timeFrame?.netDuration}") |
// timeFrame.endDate = endDate |
||||||
} |
// } else if (endDate == null) { |
||||||
|
// timeFrame.endDate = null |
||||||
} |
// } |
||||||
|
// |
||||||
} |
// owner.sessionSet = sessionSet |
||||||
|
// |
||||||
/** |
//// Timber.d("sd = : ${sessionSet.timeFrame?.startDate}, ed = ${sessionSet.timeFrame?.endDate}") |
||||||
* Multiple session sets update: |
// Timber.d("netDuration 2 = : ${sessionSet.timeFrame?.netDuration}") |
||||||
* Merges all sets into one (delete all then create a new one) |
// } |
||||||
*/ |
// |
||||||
private fun mergeSessionGroups(owner: Session, sessionSets: RealmResults<SessionSet>) { |
// } |
||||||
|
// |
||||||
var startDate: Date = this.startDate |
// } |
||||||
var endDate: Date? = this.endDate |
// |
||||||
|
// /** |
||||||
// find earlier and later dates from all sets |
// * Multiple session sets update: |
||||||
val timeFrames = sessionSets.mapNotNull { it.timeFrame } |
// * Merges all sets into one (delete all then create a new one) |
||||||
timeFrames.forEach { tf -> |
// */ |
||||||
if (tf.startDate.before(startDate)) { |
// private fun mergeSessionGroups(owner: Session, sessionSets: RealmResults<SessionSet>) { |
||||||
startDate = tf.startDate |
// |
||||||
} |
// var startDate: Date = this.startDate |
||||||
|
// var endDate: Date? = this.endDate |
||||||
endDate?.let { ed -> |
// |
||||||
tf.endDate?.let { tfed -> |
// // find earlier and later dates from all sets |
||||||
if (tfed.after(ed)) { |
// val timeFrames = sessionSets.mapNotNull { it.timeFrame } |
||||||
endDate = tfed |
// timeFrames.forEach { tf -> |
||||||
} |
// if (tf.startDate.before(startDate)) { |
||||||
} |
// startDate = tf.startDate |
||||||
} ?: run { |
// } |
||||||
endDate = tf.endDate |
// |
||||||
} |
// endDate?.let { ed -> |
||||||
|
// tf.endDate?.let { tfed -> |
||||||
} |
// if (tfed.after(ed)) { |
||||||
|
// endDate = tfed |
||||||
// get all sessions from sets |
// } |
||||||
var sessions = mutableSetOf<Session>() |
// } |
||||||
sessionSets.forEach { set -> |
// } ?: run { |
||||||
set.sessions?.asIterable()?.let { sessions.addAll(it) } |
// endDate = tf.endDate |
||||||
} |
// } |
||||||
|
// |
||||||
// delete all sets |
// } |
||||||
sessionSets.deleteAllFromRealm() |
// |
||||||
|
// // get all sessions from sets |
||||||
// Create a new sets |
// var sessions = mutableSetOf<Session>() |
||||||
val set: SessionSet = SessionSet.newInstance(this.realm) |
// sessionSets.forEach { set -> |
||||||
set.timeFrame?.let { |
// set.sessions?.asIterable()?.let { sessions.addAll(it) } |
||||||
it.setDate(startDate, endDate) |
// } |
||||||
} ?: run { |
// |
||||||
throw ModelException("TimeFrame should never be null here") |
// // delete all sets |
||||||
} |
// sessionSets.deleteAllFromRealm() |
||||||
|
// |
||||||
// Add the session linked to this timeframe to the new sessionGroup |
// // Create a new sets |
||||||
owner.sessionSet = set |
// val set: SessionSet = SessionSet.newInstance(this.realm) |
||||||
|
// set.timeFrame?.let { |
||||||
// Add all orphan sessions |
// it.setDate(startDate, endDate) |
||||||
sessions.forEach { it.sessionSet = set } |
// } ?: run { |
||||||
Timber.d("netDuration 3 = : ${set.timeFrame?.netDuration}") |
// throw ModelException("TimeFrame should never be null here") |
||||||
|
// } |
||||||
} |
// |
||||||
|
// // Add the session linked to this timeframe to the new sessionGroup |
||||||
} |
// owner.sessionSet = set |
||||||
|
// |
||||||
|
// // Add all orphan sessions |
||||||
|
// sessions.forEach { it.sessionSet = set } |
||||||
|
// Timber.d("netDuration 3 = : ${set.timeFrame?.netDuration}") |
||||||
|
// |
||||||
|
// } |
||||||
|
// |
||||||
|
//} |
||||||
|
|||||||
@ -0,0 +1,140 @@ |
|||||||
|
package net.pokeranalytics.android.model.utils |
||||||
|
|
||||||
|
import io.realm.RealmQuery |
||||||
|
import io.realm.RealmResults |
||||||
|
import net.pokeranalytics.android.model.realm.Session |
||||||
|
import net.pokeranalytics.android.model.realm.SessionSet |
||||||
|
|
||||||
|
class SessionSetManager { |
||||||
|
|
||||||
|
companion object { |
||||||
|
|
||||||
|
fun updateTimeline(session: Session) { |
||||||
|
|
||||||
|
if (!session.realm.isInTransaction) { |
||||||
|
throw IllegalStateException("realm should be in transaction at this point") |
||||||
|
} |
||||||
|
|
||||||
|
if (session.endDate == null) { |
||||||
|
throw IllegalStateException("End date should never be null here") |
||||||
|
} |
||||||
|
val endDate = session.endDate!! // tested above |
||||||
|
val startDate = session.startDate |
||||||
|
|
||||||
|
val realm = session.realm |
||||||
|
|
||||||
|
val query: RealmQuery<SessionSet> = realm.where(SessionSet::class.java) |
||||||
|
|
||||||
|
query |
||||||
|
.lessThanOrEqualTo("startDate", startDate) |
||||||
|
.greaterThanOrEqualTo("endDate", startDate) |
||||||
|
.or() |
||||||
|
.lessThanOrEqualTo("startDate", endDate) |
||||||
|
.greaterThanOrEqualTo("endDate", endDate) |
||||||
|
.or() |
||||||
|
.greaterThanOrEqualTo("startDate", startDate) |
||||||
|
.lessThanOrEqualTo("endDate", endDate) |
||||||
|
|
||||||
|
val sessionGroups = query.findAll() |
||||||
|
|
||||||
|
this.updateTimeFrames(sessionGroups, session) |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Update Time frames from sets |
||||||
|
*/ |
||||||
|
private fun updateTimeFrames(sessionSets: RealmResults<SessionSet>, session: Session) { |
||||||
|
|
||||||
|
when (sessionSets.size) { |
||||||
|
0 -> this.createOrUpdateSessionSet(session) |
||||||
|
else -> this.mergeSessionGroups(session, sessionSets) |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private fun createOrUpdateSessionSet(session: Session) { |
||||||
|
|
||||||
|
val set = session.sessionSet |
||||||
|
if (set != null) { |
||||||
|
set.startDate = session.startDate |
||||||
|
set.endDate = session.endDate!! |
||||||
|
} else { |
||||||
|
this.createSessionSet(session) |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private fun createSessionSet(session: Session) { |
||||||
|
val set: SessionSet = SessionSet.newInstance(session.realm) |
||||||
|
set.startDate = session.startDate |
||||||
|
set.endDate = session.endDate!! |
||||||
|
session.sessionSet = set |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Multiple session sets update: |
||||||
|
* Merges all sets into one (delete all then create a new one) |
||||||
|
*/ |
||||||
|
private fun mergeSessionGroups(session: Session, sessionSets: RealmResults<SessionSet>) { |
||||||
|
|
||||||
|
var startDate = session.startDate |
||||||
|
var endDate = session.endDate!! |
||||||
|
|
||||||
|
// find earlier and later dates from all sets |
||||||
|
sessionSets.forEach { set -> |
||||||
|
if (set.startDate.before(startDate)) { |
||||||
|
startDate = set.startDate |
||||||
|
} |
||||||
|
if (set.endDate.after(endDate)) { |
||||||
|
endDate = set.endDate |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// get all sessions from sets |
||||||
|
val sessions = mutableSetOf<Session>() |
||||||
|
sessionSets.forEach { set -> |
||||||
|
set.sessions?.asIterable()?.let { sessions.addAll(it) } |
||||||
|
} |
||||||
|
|
||||||
|
// delete all sets |
||||||
|
sessionSets.deleteAllFromRealm() |
||||||
|
|
||||||
|
// Create a new set |
||||||
|
val set: SessionSet = SessionSet.newInstance(session.realm) |
||||||
|
set.startDate = startDate |
||||||
|
set.endDate = endDate |
||||||
|
|
||||||
|
// Add the session linked to this timeframe to the new sessionGroup |
||||||
|
session.sessionSet = set |
||||||
|
|
||||||
|
// Add all orphan sessions |
||||||
|
sessions.forEach { it.sessionSet = set } |
||||||
|
// Timber.d("netDuration 3 = : ${set.timeFrame?.netDuration}") |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
fun removeFromTimeline(session: Session) { |
||||||
|
|
||||||
|
if (!session.realm.isInTransaction) { |
||||||
|
throw IllegalStateException("realm should be in transaction at this point") |
||||||
|
} |
||||||
|
|
||||||
|
val sessionSet = session.sessionSet |
||||||
|
if (sessionSet != null) { |
||||||
|
|
||||||
|
val sessions = mutableSetOf<Session>() |
||||||
|
sessionSet.sessions?.asIterable()?.let { sessions.addAll(it) } |
||||||
|
sessions.remove(session) |
||||||
|
|
||||||
|
sessionSet.deleteFromRealm() |
||||||
|
|
||||||
|
sessions.forEach { |
||||||
|
SessionSetManager.updateTimeline(it) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue