Makes the duration test pass!

dev_raz_wip
Laurent 7 years ago
parent 6643d33480
commit 4209ab8c2c
  1. 19
      app/build.gradle
  2. 24
      app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedTest.kt
  3. 106
      app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt
  4. 26
      app/src/androidTest/java/net/pokeranalytics/android/RealmInstrumentedUnitTest.kt
  5. 12
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  6. 8
      app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt
  7. 1
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  8. 18
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt
  9. 56
      app/src/main/java/net/pokeranalytics/android/model/realm/TimeFrame.kt
  10. 60
      app/src/test/java/net/pokeranalytics/android/ExampleUnitTest.kt
  11. 19
      app/src/test/java/net/pokeranalytics/android/RealmUnitTest.kt

@ -61,11 +61,24 @@ dependencies {
implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.jakewharton.timber:timber:4.7.1'
// Test // Test
testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test:core:1.0.0'
androidTestImplementation 'androidx.test:core:1.1.0'
androidTestImplementation 'androidx.test:runner:1.1.0' androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0' androidTestImplementation 'androidx.test:rules:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' androidTestImplementation 'androidx.test.ext:junit:1.1.0'
// Required -- JUnit 4 framework
testImplementation 'junit:junit:4.12'
// Optional -- Robolectric environment
// testImplementation 'androidx.test:core:1.1.0'
// Optional -- Mockito framework
testImplementation 'com.android.support.test:runner:1.0.1'
testImplementation 'com.android.support.test:rules:1.0.1'
// testImplementation 'androidx.test.espresso:espresso-core:3.1.0'
} }
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'

@ -1,24 +0,0 @@
package net.pokeranalytics.android
import androidx.test.InstrumentationRegistry
import androidx.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("net.pokeranalytics.android", appContext.packageName)
}
}

@ -0,0 +1,106 @@
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.Session
import net.pokeranalytics.android.model.realm.TimeFrame
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import java.text.SimpleDateFormat
import java.util.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedUnitTest : RealmInstrumentedUnitTest() {
// convenience extension
fun Session.Companion.testInstance(netResult: Double, startDate: Date, endDate: Date?): Session {
var session: Session = Session.newInstance()
session.result?.netResult = netResult
session.timeFrame?.setDate(startDate, endDate)
return session
}
@Test
fun testSessionStats() {
val realm = this.mockRealm
realm.beginTransaction()
val 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")
var s1 = realm.createObject(Session::class.java, "1")
var 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)
// var s1: Session = Session.newInstance()
// var s2: Session = Session.newInstance()
s1.result?.netResult = -100.0
s2.result?.netResult = 300.0
realm.insert(s1)
realm.insert(s2)
realm.commitTransaction()
realm.beginTransaction()
s1.timeFrame?.setDate(sd1, ed1)
s2.timeFrame?.setDate(sd2, 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 results: ComputedResults = Calculator.compute(group, Calculator.Options())
val delta = 0.01
val sum = results.computedStat(Stat.NETRESULT)
if (sum != null) {
assertEquals(200.0, sum.value, delta)
} else {
Assert.fail("No Net result stat")
}
val average = results.computedStat(Stat.AVERAGE)
if (average != null) {
assertEquals(100.0, average.value, delta)
} else {
Assert.fail("No AVERAGE stat")
}
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assertEquals(4.0, duration.value, delta)
} else {
Assert.fail("No duration stat")
}
}
}

@ -0,0 +1,26 @@
package net.pokeranalytics.android
import io.realm.Realm
import io.realm.RealmConfiguration
import org.junit.After
import org.junit.Before
open class RealmInstrumentedUnitTest {
lateinit var mockRealm: Realm
@Before
fun setup() {
val testConfig = RealmConfiguration.Builder().inMemory().name("test-realm").build()
Realm.setDefaultConfiguration(testConfig)
mockRealm = Realm.getDefaultInstance()
}
@After
@Throws(Exception::class)
public fun tearDown() {
mockRealm.close()
}
}

@ -117,12 +117,12 @@ class Calculator {
var hourlyRate: Double = 0.0; var hourlyRateBB: Double = 0.0 var hourlyRate: Double = 0.0; var hourlyRateBB: Double = 0.0
var gIndex = 0; var gSum = 0.0; var gTotalHands = 0.0; var gBBSum = 0.0; var gIndex = 0; var gSum = 0.0; var gTotalHands = 0.0; var gBBSum = 0.0;
sessionSets.forEach { group -> sessionSets.forEach { sessionSet ->
gIndex++ gIndex++
duration += group.duration duration += sessionSet.hourlyDuration
gSum += group.netResult gSum += sessionSet.netResult
gTotalHands += group.estimatedHands gTotalHands += sessionSet.estimatedHands
gBBSum += group.bbNetResult gBBSum += sessionSet.bbNetResult
hourlyRate = gSum / duration * 3600.0 hourlyRate = gSum / duration * 3600.0
hourlyRateBB = gBBSum / duration * 3600.0 hourlyRateBB = gBBSum / duration * 3600.0
@ -133,7 +133,7 @@ class Calculator {
results.addEvolutionValue(Stat.netBBPer100Hands(gBBSum, gTotalHands), duration, NET_BB_PER_100_HANDS) results.addEvolutionValue(Stat.netBBPer100Hands(gBBSum, gTotalHands), duration, NET_BB_PER_100_HANDS)
results.addEvolutionValue(hourlyRate, duration, HOURLY_RATE) results.addEvolutionValue(hourlyRate, duration, HOURLY_RATE)
results.addEvolutionValue(gIndex.toDouble(), duration, NUMBER_OF_GROUPS) results.addEvolutionValue(gIndex.toDouble(), duration, NUMBER_OF_GROUPS)
results.addEvolutionValue(group.duration, duration, DURATION) results.addEvolutionValue(sessionSet.duration.toDouble(), duration, DURATION)
results.addEvolutionValue(duration / gIndex, duration, AVERAGE_DURATION) results.addEvolutionValue(duration / gIndex, duration, AVERAGE_DURATION)
results.addEvolutionValue(hourlyRateBB, duration, HOURLY_RATE_BB) results.addEvolutionValue(hourlyRateBB, duration, HOURLY_RATE_BB)
} }

@ -2,15 +2,11 @@ package net.pokeranalytics.android.model.realm
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.PrimaryKey import io.realm.annotations.RealmClass
import java.util.*
@RealmClass
open class Result : RealmObject() { open class Result : RealmObject() {
@PrimaryKey
var id = UUID.randomUUID().toString()
// the user associated to this session result // the user associated to this session result
var player: Player? = null var player: Player? = null

@ -12,7 +12,6 @@ import net.pokeranalytics.android.util.data.sessionDao
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
open class Session : RealmObject(), SessionInterface, DynamicRowDelegate, DisplayableDataSource { open class Session : RealmObject(), SessionInterface, DynamicRowDelegate, DisplayableDataSource {
@PrimaryKey @PrimaryKey

@ -1,5 +1,6 @@
package net.pokeranalytics.android.model.realm package net.pokeranalytics.android.model.realm
import io.realm.Realm
import io.realm.RealmList import io.realm.RealmList
import io.realm.RealmObject import io.realm.RealmObject
import io.realm.annotations.Ignore import io.realm.annotations.Ignore
@ -14,7 +15,16 @@ open class SessionSet() : RealmObject() {
var sessions: RealmList<Session> = RealmList() var sessions: RealmList<Session> = RealmList()
@Ignore // a duration shortcut @Ignore // a duration shortcut
var duration: Double = 0.0 var duration: Long = 0L
get() {
return this.timeFrame?.duration ?: 0L
}
@Ignore // a duration in hour
var hourlyDuration: Double = 0.0
get() {
return this.timeFrame?.hourlyDuration ?: 0.0
}
@Ignore // a netResult shortcut @Ignore // a netResult shortcut
var netResult: Double = 0.0 var netResult: Double = 0.0
@ -30,9 +40,9 @@ open class SessionSet() : RealmObject() {
companion object { companion object {
fun newInstance() : SessionSet { fun newInstance(realm: Realm) : SessionSet {
val sessionSet: SessionSet = SessionSet() val sessionSet: SessionSet = realm.createObject(SessionSet::class.java)
sessionSet.timeFrame = TimeFrame() sessionSet.timeFrame = realm.createObject(TimeFrame::class.java)
return sessionSet return sessionSet
} }

@ -9,16 +9,21 @@ import io.realm.annotations.LinkingObjects
import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.exceptions.ModelException
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 private set(value) {
field = value
this.computeDuration()
}
// An end date // An end date
var endDate: Date? = null var endDate: Date? = null
private set private set(value) {
field = value
this.computeDuration()
}
// The break duration // The break duration
var breakDuration: Long = 0L var breakDuration: Long = 0L
@ -31,6 +36,11 @@ open class TimeFrame : RealmObject() {
var duration: Long = 0L var duration: Long = 0L
private set private set
var hourlyDuration: Double = 0.0
get() {
return this.duration / 3600000.0 // 3.6 millions of milliseconds
}
// indicates a state of pause // indicates a state of pause
var paused: Boolean = false var paused: Boolean = false
@ -63,7 +73,8 @@ open class TimeFrame : RealmObject() {
private fun computeDuration() { private fun computeDuration() {
var endDate: Date = this.endDate ?: Date() var endDate: Date = this.endDate ?: Date()
this.duration = endDate.time - startDate.time - this.breakDuration val netDuration = endDate.time - this.startDate.time - this.breakDuration
this.duration = netDuration
} }
private fun notifySessionDateChange() { private fun notifySessionDateChange() {
@ -76,13 +87,13 @@ open class TimeFrame : RealmObject() {
} else { } else {
val endDate = this.endDate!! val endDate = this.endDate!!
query query
.greaterThan("timeFrame.startDate", this.startDate.time) .greaterThan("timeFrame.startDate", this.startDate)
.lessThan("timeFrame.endDate", this.startDate.time) .lessThan("timeFrame.endDate", this.startDate)
.or() .or()
.greaterThan("timeFrame.startDate", endDate) .greaterThan("timeFrame.startDate", endDate)
.lessThan("timeFrame.endDate", endDate) .lessThan("timeFrame.endDate", endDate)
.or() .or()
.lessThan("timeFrame.startDate", this.startDate.time) .lessThan("timeFrame.startDate", this.startDate)
.greaterThan("timeFrame.endDate", endDate) .greaterThan("timeFrame.endDate", endDate)
} }
@ -90,7 +101,7 @@ open class TimeFrame : RealmObject() {
this.updateTimeFrames(sessionGroups) this.updateTimeFrames(sessionGroups)
realm.close() // realm.close()
} }
/** /**
@ -112,17 +123,24 @@ open class TimeFrame : RealmObject() {
private fun createSessionGroup() { private fun createSessionGroup() {
val realm = Realm.getDefaultInstance() val realm = Realm.getDefaultInstance()
realm.beginTransaction() // realm.beginTransaction()
val set: SessionSet = SessionSet.newInstance() val set: SessionSet = SessionSet.newInstance(realm)
set.timeFrame?.let { set.timeFrame?.let {
it.startDate = this.startDate it.startDate = this.startDate
it.endDate = this.endDate it.endDate = this.endDate
} ?: run { } ?: run {
throw ModelException("TimeFrame should never be null here") throw ModelException("TimeFrame should never be null here")
} }
set.sessions.add(this.session)
realm.commitTransaction() this.session?.let {
it.sessionSet = set
} ?: run {
throw ModelException("Session should never be null here")
}
// this.session?.sessionSet = set
// set.sessions.add(this.session)
// realm.commitTransaction()
} }
/** /**
@ -144,13 +162,13 @@ open class TimeFrame : RealmObject() {
} }
// Realm Update // Realm Update
val realm = Realm.getDefaultInstance() // val realm = Realm.getDefaultInstance()
realm.beginTransaction() realm.beginTransaction()
if (!sessionSet.sessions.contains(this.session)) { if (!sessionSet.sessions.contains(this.session)) {
sessionSet.sessions.add(this.session) sessionSet.sessions.add(this.session)
} }
realm.copyToRealmOrUpdate(groupTimeFrame) // realm.copyToRealmOrUpdate(groupTimeFrame)
realm.commitTransaction() // realm.commitTransaction()
} }
@ -185,14 +203,14 @@ open class TimeFrame : RealmObject() {
var sessions = sessionSets.flatMap { it.sessions } var sessions = sessionSets.flatMap { it.sessions }
// Start Realm updates // Start Realm updates
val realm = Realm.getDefaultInstance() // val realm = Realm.getDefaultInstance()
realm.beginTransaction() // realm.beginTransaction()
// delete all sets // delete all sets
sessionSets.deleteAllFromRealm() sessionSets.deleteAllFromRealm()
// Create a new sets // Create a new sets
val set: SessionSet = SessionSet.newInstance() val set: SessionSet = SessionSet.newInstance(realm)
set.timeFrame?.let { set.timeFrame?.let {
it.startDate = startDate it.startDate = startDate
it.endDate = endDate it.endDate = endDate
@ -210,7 +228,7 @@ open class TimeFrame : RealmObject() {
// Add all orphan sessions // Add all orphan sessions
set.sessions.addAll(sessions) set.sessions.addAll(sessions)
realm.commitTransaction() // realm.commitTransaction()
} }
} }

@ -1,11 +1,9 @@
package net.pokeranalytics.android package net.pokeranalytics.android
import net.pokeranalytics.android.calculus.* import net.pokeranalytics.android.calculus.*
import net.pokeranalytics.android.model.realm.Session
import net.pokeranalytics.android.model.realm.SessionSet import net.pokeranalytics.android.model.realm.SessionSet
import org.junit.Assert.fail import org.junit.Assert.fail
import org.junit.Test import org.junit.Test
import java.util.*
/** /**
* Example local unit test, which will execute on the development machine (host). * Example local unit test, which will execute on the development machine (host).
@ -27,7 +25,7 @@ class ExampleUnitTest : RealmUnitTest() {
} }
// @Test @Test
fun testStats() { fun testStats() {
val grades: List<Grade> = listOf(Grade(10.0), Grade(20.0)) val grades: List<Grade> = listOf(Grade(10.0), Grade(20.0))
@ -51,61 +49,5 @@ class ExampleUnitTest : RealmUnitTest() {
} }
// convenience extension
fun Session.Companion.testInstance(netResult: Double, startDate: Date, endDate: Date?): Session {
var session: Session = Session.newInstance()
session.result?.netResult = netResult
session.timeFrame?.setDate(startDate, endDate)
return session
}
@Test
fun testSessionStats() {
val realm = RealmUnitTest.realmInstance()
realm.beginTransaction()
Calendar.getInstance().set(2019,1,1,10,0)
val sd1 = Calendar.getInstance().time
Calendar.getInstance().set(2019,1,1,11,0)
val ed1 = Calendar.getInstance().time
val s1 = Session.testInstance(-100.0, sd1, ed1)
Calendar.getInstance().set(2019,1,2,8,0)
val sd2 = Calendar.getInstance().time
Calendar.getInstance().set(2019,1,2,11,0)
val ed2 = Calendar.getInstance().time
val s2 = Session.testInstance(300.0, sd2, ed2)
val sessions: List<Session> = listOf(s1, s2)
val group = SessionGroup(name = "test", sessions = sessions)
realm.commitTransaction()
val results: ComputedResults = Calculator.compute(group, Calculator.Options())
val sum = results.computedStat(Stat.NETRESULT)
if (sum != null) {
assert(sum.value == 200.0) { "sum is ${sum.value}" }
} else {
fail("No Net result stat")
}
val average = results.computedStat(Stat.AVERAGE)
if (average != null) {
assert(average.value == 100.0) { "average is ${average.value}" }
} else {
fail("No AVERAGE stat")
}
val duration = results.computedStat(Stat.DURATION)
if (duration != null) {
assert(duration.value == 4.0) { "duration is ${duration.value}" }
} else {
fail("No AVERAGE stat")
}
}
} }

@ -1,22 +1,25 @@
package net.pokeranalytics.android package net.pokeranalytics.android
//import androidx.test.core.app.ApplicationProvider
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import org.junit.After
import org.junit.Before
open class RealmUnitTest { open class RealmUnitTest {
companion object { lateinit var mockRealm: Realm
fun realmInstance() : Realm { @Before
fun setup() {
// Application
// Realm.init(ApplicationProvider.getApplicationContext<PokerAnalyticsApplication>())
val testConfig = RealmConfiguration.Builder().inMemory().name("test-realm").build() val testConfig = RealmConfiguration.Builder().inMemory().name("test-realm").build()
return Realm.getInstance(testConfig) Realm.setDefaultConfiguration(testConfig)
mockRealm = Realm.getDefaultInstance()
} }
@After
@Throws(Exception::class)
public fun tearDown() {
mockRealm.close()
} }
} }
Loading…
Cancel
Save