# Conflicts: # app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.ktfeature/top10
commit
d083824428
@ -0,0 +1,82 @@ |
||||
package net.pokeranalytics.android |
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4 |
||||
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.Bankroll |
||||
import net.pokeranalytics.android.model.realm.Currency |
||||
import net.pokeranalytics.android.model.realm.Session |
||||
import org.junit.Assert |
||||
import org.junit.Test |
||||
import org.junit.runner.RunWith |
||||
import java.util.* |
||||
|
||||
@RunWith(AndroidJUnit4::class) |
||||
class BankrollInstrumentedUnitTest : 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") |
||||
|
||||
val br1 = realm.createObject(Bankroll::class.java, "1") |
||||
val br2 = realm.createObject(Bankroll::class.java, "2") |
||||
|
||||
val c1 = realm.createObject(Currency::class.java, "1") |
||||
val c2 = realm.createObject(Currency::class.java, "2") |
||||
c1.rate = 0.1 |
||||
c2.rate = 2.0 |
||||
br1.currency = c1 |
||||
br2.currency = c2 |
||||
|
||||
s1.bankroll = br1 |
||||
s2.bankroll = br2 |
||||
|
||||
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?.netResult = 100.0 |
||||
s2.result?.netResult = 200.0 |
||||
|
||||
realm.commitTransaction() |
||||
|
||||
val sessions = realm.where(Session::class.java).findAll() |
||||
val group = SessionGroup(name = "test", sessions = sessions) |
||||
|
||||
val options = Calculator.Options() |
||||
|
||||
val results: ComputedResults = Calculator.compute(group, options) |
||||
val delta = 0.01 |
||||
|
||||
val sum = results.computedStat(Stat.NETRESULT) |
||||
if (sum != null) { |
||||
Assert.assertEquals(410.0, sum.value, delta) |
||||
} else { |
||||
Assert.fail("No Net result stat") |
||||
} |
||||
|
||||
val average = results.computedStat(Stat.AVERAGE) |
||||
if (average != null) { |
||||
Assert.assertEquals(205.0, average.value, delta) |
||||
} else { |
||||
Assert.fail("No AVERAGE stat") |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -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,26 @@ |
||||
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 computeNetDuration() { |
||||
this.netDuration = this.endDate().time - this.startDate.time - this.breakDuration |
||||
} |
||||
|
||||
var hourlyDuration: Double |
||||
get() = this.netDuration / 3600000.0 |
||||
set(value) = TODO() |
||||
|
||||
} |
||||
@ -1,280 +1,288 @@ |
||||
package net.pokeranalytics.android.model.realm |
||||
|
||||
import io.realm.RealmObject |
||||
import io.realm.RealmQuery |
||||
import io.realm.RealmResults |
||||
import io.realm.annotations.Ignore |
||||
import io.realm.annotations.LinkingObjects |
||||
import net.pokeranalytics.android.exceptions.ModelException |
||||
import timber.log.Timber |
||||
import java.util.* |
||||
|
||||
open class TimeFrame : RealmObject() { |
||||
|
||||
// A start date |
||||
var startDate: Date = Date() |
||||
private set(value) { |
||||
field = value |
||||
this.computeDuration() |
||||
} |
||||
|
||||
// An end date |
||||
var endDate: Date? = null |
||||
private set(value) { |
||||
field = value |
||||
this.computeDuration() |
||||
} |
||||
|
||||
// The latest pause date |
||||
var pauseDate: Date? = null |
||||
set(value) { |
||||
field?.let { |
||||
if (value == null && field != null) { |
||||
breakDuration += Date().time - it.time |
||||
} |
||||
} |
||||
field = value |
||||
this.computeDuration() |
||||
} |
||||
|
||||
// The break netDuration |
||||
var breakDuration: Long = 0L |
||||
set(value) { |
||||
field = value |
||||
this.computeDuration() |
||||
} |
||||
|
||||
// the total netDuration |
||||
var netDuration: Long = 0L |
||||
private set |
||||
|
||||
var hourlyDuration: Double = 0.0 |
||||
get() { |
||||
return this.netDuration / 3600000.0 // 3.6 millions of milliseconds |
||||
} |
||||
|
||||
// indicates a state of pause |
||||
var paused: Boolean = false |
||||
|
||||
// Session |
||||
@LinkingObjects("timeFrame") |
||||
private val sessions: RealmResults<Session>? = null // we should have only one session |
||||
|
||||
@Ignore |
||||
var session: Session? = null |
||||
get() = if (this.sessions != null && this.sessions.isEmpty()) null else this.sessions?.first() |
||||
|
||||
// Group |
||||
@LinkingObjects("timeFrame") |
||||
private val sets: RealmResults<SessionSet>? = null // we should have only one sessionGroup |
||||
|
||||
@Ignore |
||||
var set: SessionSet? = null |
||||
get() = this.sets?.first() |
||||
|
||||
fun setStart(startDate: Date) { |
||||
this.startDate = startDate |
||||
this.session?.let { |
||||
this.notifySessionDateChange(it) |
||||
} |
||||
} |
||||
|
||||
fun setEnd(endDate: Date?) { |
||||
this.endDate = endDate |
||||
this.session?.let { |
||||
this.notifySessionDateChange(it) |
||||
} |
||||
} |
||||
|
||||
fun setDate(startDate: Date, endDate: Date?) { |
||||
this.startDate = startDate |
||||
this.endDate = endDate |
||||
|
||||
this.session?.let { |
||||
this.notifySessionDateChange(it) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Computes the net netDuration of the session |
||||
*/ |
||||
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 |
||||
*/ |
||||
fun notifySessionDateChange(owner: Session) { |
||||
|
||||
var query: RealmQuery<SessionSet> = this.realm.where(SessionSet::class.java) |
||||
query.isNotNull("timeFrame") |
||||
|
||||
// Timber.d("this> sd = : ${this.startDate}, ed = ${this.endDate}") |
||||
|
||||
val sets = realm.where(SessionSet::class.java).findAll() |
||||
// Timber.d("set count = ${sets.size}") |
||||
|
||||
if (this.endDate == null) { |
||||
query.greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||
.or() |
||||
.greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
||||
.or() |
||||
.isNull("timeFrame.endDate") |
||||
} else { |
||||
val endDate = this.endDate!! |
||||
query |
||||
.lessThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||
.greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
||||
.or() |
||||
.lessThanOrEqualTo("timeFrame.startDate", endDate) |
||||
.greaterThanOrEqualTo("timeFrame.endDate", endDate) |
||||
.or() |
||||
.greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||
.lessThanOrEqualTo("timeFrame.endDate", endDate) |
||||
.or() |
||||
.isNull("timeFrame.endDate") |
||||
.lessThanOrEqualTo("timeFrame.startDate", endDate) |
||||
} |
||||
|
||||
val sessionGroups = query.findAll() |
||||
|
||||
this.updateTimeFrames(sessionGroups, owner) |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Update Time frames from sets |
||||
*/ |
||||
private fun updateTimeFrames(sessionSets: RealmResults<SessionSet>, owner: Session) { |
||||
|
||||
when (sessionSets.size) { |
||||
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 createSessionGroup(owner: Session) { |
||||
|
||||
val set: SessionSet = SessionSet.newInstance(this.realm) |
||||
set.timeFrame?.let { |
||||
it.startDate = this.startDate |
||||
it.endDate = this.endDate |
||||
} ?: run { |
||||
throw ModelException("TimeFrame should never be null here") |
||||
} |
||||
|
||||
owner.sessionSet = set |
||||
|
||||
// Timber.d("sd = : ${set.timeFrame?.startDate}, ed = ${set.timeFrame?.endDate}") |
||||
Timber.d("netDuration 1 = : ${set.timeFrame?.netDuration}") |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Single SessionSet update, the session might be the owner |
||||
* Changes the sessionGroup timeframe using the current timeframe dates |
||||
*/ |
||||
private fun updateSessionGroup(owner: Session, sessionSet: SessionSet) { |
||||
|
||||
var timeFrame: TimeFrame = sessionSet.timeFrame!! // tested in the query |
||||
//package net.pokeranalytics.android.model.realm |
||||
// |
||||
//import io.realm.RealmObject |
||||
//import io.realm.RealmQuery |
||||
//import io.realm.RealmResults |
||||
//import io.realm.annotations.Ignore |
||||
//import io.realm.annotations.LinkingObjects |
||||
//import net.pokeranalytics.android.exceptions.ModelException |
||||
//import timber.log.Timber |
||||
//import java.util.* |
||||
// |
||||
//open class TimeFrame : RealmObject() { |
||||
// |
||||
// // A start date |
||||
// var startDate: Date = Date() |
||||
// private set(value) { |
||||
// field = value |
||||
// this.computeNetDuration() |
||||
// } |
||||
// |
||||
// // An end date |
||||
// var endDate: Date? = null |
||||
// private set(value) { |
||||
// field = value |
||||
// this.computeNetDuration() |
||||
// } |
||||
// |
||||
// // The latest pause date |
||||
// var pauseDate: Date? = null |
||||
// set(value) { |
||||
// field?.let { |
||||
// if (value == null && field != null) { |
||||
// breakDuration += Date().time - it.time |
||||
// } |
||||
// } |
||||
// field = value |
||||
// this.computeNetDuration() |
||||
// } |
||||
// |
||||
// // The break netDuration |
||||
// var breakDuration: Long = 0L |
||||
// set(value) { |
||||
// field = value |
||||
// this.computeNetDuration() |
||||
// } |
||||
// |
||||
// // the total netDuration |
||||
// var netDuration: Long = 0L |
||||
// private set |
||||
// |
||||
// var hourlyDuration: Double = 0.0 |
||||
// get() { |
||||
// return this.netDuration / 3600000.0 // 3.6 millions of milliseconds |
||||
// } |
||||
// |
||||
// // Session |
||||
// @LinkingObjects("timeFrame") |
||||
// private val sessions: RealmResults<Session>? = null // we should have only one session |
||||
// |
||||
// @Ignore |
||||
// var session: Session? = null |
||||
// get() = if (this.sessions != null && this.sessions.isEmpty()) null else this.sessions?.first() |
||||
// |
||||
// // Group |
||||
// @LinkingObjects("timeFrame") |
||||
// private val sets: RealmResults<SessionSet>? = null // we should have only one sessionGroup |
||||
// |
||||
// @Ignore |
||||
// var set: SessionSet? = null |
||||
// get() = this.sets?.first() |
||||
// |
||||
// fun setStart(startDate: Date) { |
||||
// this.startDate = startDate |
||||
// this.session?.let { |
||||
// this.notifySessionDateChange(it) |
||||
// } |
||||
// } |
||||
// |
||||
// fun setEnd(endDate: Date?) { |
||||
// this.endDate = endDate |
||||
// this.session?.let { |
||||
// this.notifySessionDateChange(it) |
||||
// } |
||||
// } |
||||
// |
||||
// fun setDate(startDate: Date, endDate: Date?) { |
||||
// this.startDate = startDate |
||||
// this.endDate = endDate |
||||
// |
||||
// this.session?.let { |
||||
// this.notifySessionDateChange(it) |
||||
// } |
||||
// } |
||||
// |
||||
// /** |
||||
// * Computes the net netDuration of the session |
||||
// */ |
||||
// private fun computeNetDuration() { |
||||
// 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 |
||||
// */ |
||||
// fun notifySessionDateChange(owner: Session) { |
||||
// |
||||
// var query: RealmQuery<SessionSet> = this.realm.where(SessionSet::class.java) |
||||
// query.isNotNull("timeFrame") |
||||
// |
||||
//// Timber.d("this> sd = : ${this.startDate}, ed = ${this.endDate}") |
||||
// |
||||
// val sets = realm.where(SessionSet::class.java).findAll() |
||||
//// Timber.d("set count = ${sets.size}") |
||||
// |
||||
// if (this.endDate == null) { |
||||
// query.greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||
// .or() |
||||
// .greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
||||
// .or() |
||||
// .isNull("timeFrame.endDate") |
||||
// } else { |
||||
// val endDate = this.endDate!! |
||||
// query |
||||
// .lessThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||
// .greaterThanOrEqualTo("timeFrame.endDate", this.startDate) |
||||
// .or() |
||||
// .lessThanOrEqualTo("timeFrame.startDate", endDate) |
||||
// .greaterThanOrEqualTo("timeFrame.endDate", endDate) |
||||
// .or() |
||||
// .greaterThanOrEqualTo("timeFrame.startDate", this.startDate) |
||||
// .lessThanOrEqualTo("timeFrame.endDate", endDate) |
||||
// .or() |
||||
// .isNull("timeFrame.endDate") |
||||
// .lessThanOrEqualTo("timeFrame.startDate", endDate) |
||||
// } |
||||
// |
||||
// val sessionGroups = query.findAll() |
||||
// |
||||
// this.updateTimeFrames(sessionGroups, owner) |
||||
// |
||||
// } |
||||
// |
||||
// /** |
||||
// * Update Time frames from sets |
||||
// */ |
||||
// private fun updateTimeFrames(sessionSets: RealmResults<SessionSet>, owner: Session) { |
||||
// |
||||
// when (sessionSets.size) { |
||||
// 0 -> this.createOrUpdateSessionSet(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) { |
||||
// |
||||
// val set = owner.sessionSet |
||||
// if (set != null) { |
||||
// set.timeFrame?.startDate = this.startDate |
||||
// set.timeFrame?.endDate = this.endDate |
||||
// } else { |
||||
// this.createSessionSet(owner) |
||||
// } |
||||
// |
||||
//// Timber.d("sd = : ${set.timeFrame?.startDate}, ed = ${set.timeFrame?.endDate}") |
||||
// Timber.d("netDuration 1 = : ${set?.timeFrame?.netDuration}") |
||||
// |
||||
// } |
||||
// |
||||
// fun createSessionSet(owner: Session) { |
||||
// val set: SessionSet = SessionSet.newInstance(this.realm) |
||||
// set.timeFrame?.let { |
||||
// it.startDate = this.startDate |
||||
// it.endDate = this.endDate |
||||
// } ?: run { |
||||
// throw ModelException("TimeFrame should never be null here") |
||||
// } |
||||
// |
||||
// owner.sessionSet = set |
||||
// } |
||||
// |
||||
// |
||||
// /** |
||||
// * Single SessionSet update, the session might be the owner |
||||
// * Changes the sessionGroup timeframe using the current timeframe dates |
||||
// */ |
||||
// private fun updateSessionGroup(owner: Session, sessionSet: SessionSet) { |
||||
// |
||||
// var timeFrame: TimeFrame = sessionSet.timeFrame!! // tested in the query |
||||
//// timeFrame.setDate(this.startDate, this.endDate) |
||||
// |
||||
// val sisterSessions = sessionSet.sessions!! // shouldn't crash ever |
||||
// |
||||
// // 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) { |
||||
// timeFrame.setDate(this.startDate, this.endDate) |
||||
|
||||
val sisterSessions = sessionSet.sessions!! // shouldn't crash ever |
||||
|
||||
// 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) { |
||||
timeFrame.setDate(this.startDate, this.endDate) |
||||
} else { // there are 2+ sessions to manage and possible splits |
||||
|
||||
val endDate = this.endDate |
||||
|
||||
// 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) { |
||||
var sessions = mutableListOf<Session>(owner) |
||||
sessionSet.sessions?.forEach { sessions.add(it) } |
||||
sessionSet.deleteFromRealm() |
||||
sessions.forEach { it.timeFrame?.notifySessionDateChange(it) } |
||||
} else { |
||||
|
||||
if (this.startDate.before(timeFrame.startDate)) { |
||||
timeFrame.startDate = this.startDate |
||||
} |
||||
if (endDate != null && timeFrame.endDate != null && endDate.after(timeFrame.endDate)) { |
||||
timeFrame.endDate = endDate |
||||
} else if (endDate == null) { |
||||
timeFrame.endDate = null |
||||
} |
||||
|
||||
owner.sessionSet = sessionSet |
||||
|
||||
// Timber.d("sd = : ${sessionSet.timeFrame?.startDate}, ed = ${sessionSet.timeFrame?.endDate}") |
||||
Timber.d("netDuration 2 = : ${sessionSet.timeFrame?.netDuration}") |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* Multiple session sets update: |
||||
* 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 |
||||
val timeFrames = sessionSets.mapNotNull { it.timeFrame } |
||||
timeFrames.forEach { tf -> |
||||
if (tf.startDate.before(startDate)) { |
||||
startDate = tf.startDate |
||||
} |
||||
|
||||
endDate?.let { ed -> |
||||
tf.endDate?.let { tfed -> |
||||
if (tfed.after(ed)) { |
||||
endDate = tfed |
||||
} |
||||
} |
||||
} ?: run { |
||||
endDate = tf.endDate |
||||
} |
||||
|
||||
} |
||||
|
||||
// get all sessions from sets |
||||
var sessions = mutableSetOf<Session>() |
||||
sessionSets.forEach { set -> |
||||
set.sessions?.asIterable()?.let { sessions.addAll(it) } |
||||
} |
||||
|
||||
// delete all sets |
||||
sessionSets.deleteAllFromRealm() |
||||
|
||||
// Create a new sets |
||||
val set: SessionSet = SessionSet.newInstance(this.realm) |
||||
set.timeFrame?.let { |
||||
it.setDate(startDate, endDate) |
||||
} ?: run { |
||||
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}") |
||||
|
||||
} |
||||
|
||||
} |
||||
// } else { // there are 2+ sessions to manage and possible splits |
||||
// |
||||
// val endDate = this.endDate |
||||
// |
||||
// // 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) { |
||||
// var sessions = mutableListOf<Session>(owner) |
||||
// sessionSet.sessions?.forEach { sessions.add(it) } |
||||
// sessionSet.deleteFromRealm() |
||||
// sessions.forEach { it.timeFrame?.notifySessionDateChange(it) } |
||||
// } else { |
||||
// |
||||
// if (this.startDate.before(timeFrame.startDate)) { |
||||
// timeFrame.startDate = this.startDate |
||||
// } |
||||
// if (endDate != null && timeFrame.endDate != null && endDate.after(timeFrame.endDate)) { |
||||
// timeFrame.endDate = endDate |
||||
// } else if (endDate == null) { |
||||
// timeFrame.endDate = null |
||||
// } |
||||
// |
||||
// owner.sessionSet = sessionSet |
||||
// |
||||
//// Timber.d("sd = : ${sessionSet.timeFrame?.startDate}, ed = ${sessionSet.timeFrame?.endDate}") |
||||
// Timber.d("netDuration 2 = : ${sessionSet.timeFrame?.netDuration}") |
||||
// } |
||||
// |
||||
// } |
||||
// |
||||
// } |
||||
// |
||||
// /** |
||||
// * Multiple session sets update: |
||||
// * 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 |
||||
// val timeFrames = sessionSets.mapNotNull { it.timeFrame } |
||||
// timeFrames.forEach { tf -> |
||||
// if (tf.startDate.before(startDate)) { |
||||
// startDate = tf.startDate |
||||
// } |
||||
// |
||||
// endDate?.let { ed -> |
||||
// tf.endDate?.let { tfed -> |
||||
// if (tfed.after(ed)) { |
||||
// endDate = tfed |
||||
// } |
||||
// } |
||||
// } ?: run { |
||||
// endDate = tf.endDate |
||||
// } |
||||
// |
||||
// } |
||||
// |
||||
// // get all sessions from sets |
||||
// var sessions = mutableSetOf<Session>() |
||||
// sessionSets.forEach { set -> |
||||
// set.sessions?.asIterable()?.let { sessions.addAll(it) } |
||||
// } |
||||
// |
||||
// // delete all sets |
||||
// sessionSets.deleteAllFromRealm() |
||||
// |
||||
// // Create a new sets |
||||
// val set: SessionSet = SessionSet.newInstance(this.realm) |
||||
// set.timeFrame?.let { |
||||
// it.setDate(startDate, endDate) |
||||
// } ?: run { |
||||
// 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